【JavaEE】【多线程】进程与线程的概念


进程

进程是操作系统对一个正在运行的程序的一种抽象,可以把进程看做程序的一次运行过程;
同时,在操作系统内部,进程又是操作系统进行资源分配的基本单位。

系统管理进程

  • 先描述一个进程:
    使用结构体(因为操作系统主要由c语言写成),再描述出进程的核心属性即进程控制块PCB(Process Control Block)。
  • 把多个进程组织起来:
    使用数据结构组织起来,Linux使用链表来组织。

系统操作进程

  • 进程的创建:创建一个PCB,初始化各个属性,加入到数据结构中。
  • 进程的销毁:在数据结构中找到并删除。
  • 查看进程列表:遍历查找到进程,现显示关键数据。

进程控制块PCB关键属性

  • pid (进程id):相当于身份证,每个进程不一样。
  • 一组内存指针:指向进程执行的指令,依赖。
  • 文件描述符表:进程运行时,多数要与硬盘进行交互,硬盘储存数据的方式是通过文件存储,而文件的信息就保存在文件描述符表中。操作系统回将很多资源抽象为文件。
  • 进程状态:两个主要的进程状态:1.就绪状态:进程随时能到CPU上执行,2.阻塞状态:进程当前不适合在CPU上执行。
  • 进程优先级:优先级越高,分配的CPU资源越多。
  • 进程的上下文:进程的调度原理,会使得进程在执行了一会之后会失去CPU,CPU再次执行回来时,要沿着上次结束状态执行。
    而进程在CPU上运行时,床铺上的各种寄存器就会记录当前进程的中间状态,
    将寄存器的各种记录保存到pcb对应属性,下次执行时又返回给对应寄存器就恢复了进程上下文。
  • 进程的记账信息:统计每个进程在CPU上执行了多久。如果该进程长时间没分配到CPU资源,就会给这个进程倾斜一些CPU资源。

cpu对进程的操作

CPU对进程的操作是 分时复用
分时复用就是指:把一份时间分为多份,每份时间执行对应的进程。由于CPU运行速度快,让进程切换的时间超过了肉眼反应。

并发执行:一个CPU核心上按照分时复用执行进程。
并行执行:多个CPU核心执行多个进程。
现代CPU都是两者兼备。

由于代码无法区分,平时就将两者合起来叫做“并发”

进程调度

进程调度就是指操作系统在并发执行进程时,进程之间的相互切换。
而上面PCB中的进程状态,进程优先级,进程上下文,进程记账信息就是支持进程调度的。

线程

线程:一个线程就是一个 “执行流”. 每个线程之间都可以按照顺讯执行自己的代码。就相当于是一个轻量级的进程。

线程与进程

线程与进程的关系是包含关系,每个进程中至少要有一个线程。
相当于周计划(进程)与日计划(线程)的关系。

线程资源分配

每个进程的创建需要申请资源,销毁需要释放资源。
而在一个进程中只有第一个线程创建需要申请资源,所有线程销毁完才需要释放资源。

而在一个进程中所有线程共享资源,这样会带来如果一个线程出问题,可能所有线程就出问题了。就像一个线程中抛出一个异常没处理,就将整个进程中的线程全部搞挂。
这样的好处是开销小,效率高,但是如果线程过多也会使线程调度开销大,影响效率。

线程调度

操作系统操作线程(一个进程内)也和进程一样有并发执行和并行执行。
线程也有线程状态,线程优先级,线程上下文,线程记账信息(与上诉进程的介绍一样,只需把进程改为线程即可)。
而内存指针和文件描述符表是一个进程中所有线程共享的。

线程与进程区别

  1. 进程是系统进行资源分配和调度的一个独立单位,线程是程序执行的最小单位。
  2. 进程有自己的内存地址空间,线程只独享指令流执行的必要资源,如寄存器和栈。
  3. 由于同一进程的各线程间共享内存和文件资源,可以不通过内核进行直接通信。
  4. 线程的创建、切换及终止效率更高。

线程简单操作代码

创建线程

创建线程有两种方式:

  • 使用类继承Thread类,重写run方法。在主函数中创建好对象后调用start方法就创建好了一个线程。
class MyThread extends Thread {
    @Override
    public void run() {
        //写代码
    }
}
public class Demo1 {
    public static void main(String[] args) {
        Thread thread = new MyThread();
        thread.start();

    }
}

  • 实现Runnable接口,重写run方法,通过Thread创建对象时,将实现Runnable接口的类对象传到构造函数中,在调用start方法。
class MyRunnable implements Runnable {
    @Override
    public void run() {
        
    }
}


public class Demo2 {
    public static void main(String[] args) {
        MyRunnable myRunnable = new MyRunnable();
        Thread thread = new Thread(myRunnable);
        thread.start();
    }
}

  • 还可以使用匿名内部类
Thread thread = new Thread() {
@Override
    public void run() {
        //写代码
    }
}


Thread thread = new Thread(new Runnable) {
@Override
    public void run() {
        //写代码
    }
}
  • lambda 表达式
Thread thread = new Thread ( () -> {
 //写代码不用重写run方法
});

Thread thread = new Thread( (new Runnable) ->{
//写代码不用重写run方法
});

查看线程

在当前电脑上看由Java写的线程可以找到安装使用的JDK写的bin目录里面的Jconsole.exe程序。

运行这个程序里面就可以看当前的线程。

评论 32
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值