[并发概念] 进程与线程

使用通俗易懂的语言讲述多线程领域最重要的概念。

多线程概念初识分为四个小节。

  1. 线程与进程
  2. 串行、并行、并发
  3. 多线程与高并发
  4. 同步/异步、阻塞/非阻塞

进程和线程

操作系统是包含多个进程的容器,每个进程又都是容纳多个线程的容器。
在这里插入图片描述

Oracle官方文档中的定义

https://docs.oracle.com/cd/E19455-01/806-5257/6je9h032b/index.html

  • 进程:通过fork(2)系统调用创建的UNIX环境(例如文件描述符,用户ID等),它被设置为运行程序。
  • 线程:在进程上下文中执行的一系列指令

什么是进程

进程的英文是Process,指的是程序的一次执行。在用户下达运行程序的命令后,就会产生进程。

以王者荣耀游戏为例,程序安装到手机中,占用2GB左右磁盘空间。平时不允许游戏时,不会耗电、内存、CPU,因为它是一堆代码和资源放置在磁盘中,没有执行。游戏启动后,程序才会变成进程,占用内存,消耗CPU等。进程可以视作对代码的实例化,每次运行的进程也不尽相同。

Windows资源管理器展示的就是已经运行起来的进程。

在这里插入图片描述

总结:进程是程序(我们写的代码)的真正运行实例,是资源分配的基本单位。

什么是线程

线程是CPU的基本调度单位,每个线程执行的都是进程代码的某个片段。

演示实例:通过任务管理器监视运行Java程序后的线程数变化

public static void main(String[] args) {
    for(int i = 0; i < 200; i++) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(10000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
}

执行代码创建200个线程时,系统新增一个java.exe进程,线程是227个。
在这里插入图片描述

情景解释:我们将房间视为1个进程,而房间中的2个人视为两个线程。房间有很多自己的属性,例如15平方、床、电视等,房间并没有做任何事情,真正做事是房间中的2个人。人在房间中可以看电视睡觉,可以比喻进程中的线程执行不同功能的代码。因此,进程是线程的容器,线程利用资源,执行代码,实现所需的效果。

进程和线程的不同

进程与线程有着相似的生命周期,都有着就绪、等待、终止等状态。不同之处有很多。

1. 起源不同

先有进程,后有线程。CPU处理速度远远快于内存等外设的速度,线程的出现时为了提高CPU的利用率和程序的执行效率。

2. 概念不同

进程是具有独立功能程序的一次运行,是系统分配资源和调度的单位,而线程是CPU的基本调度单位。

3. 内存分享方式不同

操作系统会给每个进程分配一定的内存,但进程之间内存是不共享的。进程之间通信需要通过IPC(进程间通信)实现。进程内部线程可以访问共享内存,不需要额外处理。

4. 拥有资源不同

线程是进程的一部分。线程共享的内容包括(1)进程代码段;(2)进程的公有数据(便于线程之间通信);(3)进程打开的文件描述符;(4)信号的处理器;(5)进程的当前目录;(6)进程用户ID与进程组ID。
线程独有的内容包括(1)线程ID;(2)寄存器组的值;(3)线程的堆栈;(4)错误返回码;(5)线程的信号屏蔽码。

5. 数量不同

一个进程可以有多个线程,但至少有一个线程。

6. 开销不同

  1. 线程的创建、终止时间比进程短
  2. 同一进程的线程切换时间比进程切换短
  3. 同一进程的各个线程间共享内存和文件资源,可以不通过内核进行通信。

Java语言与多线程的渊源

Java设计之初就已经支持多线程,经常用于服务端开发。

此外,Java语言的多线程是一对一映射到操作系统的内核线程。有些语言的线程是虚拟线程,不会在操作系统中对应建立一个线程。例如上面的例子,我们通过代码创建200个线程,实实在在的在操作系统中创建了200个线程。

debug运行简单的Java程序,可以注意JVM启动了多个核心线程。。

public static void main(String[] args) {
    System.out.println("Hello Threads");
}

在这里插入图片描述

JVM核心线程介绍

  1. main:主线程,用户程序的入口
  2. Signal Dispatcher(信号分配器):把操作系统发送给JVM的信号分发给适当的处理程序。
  3. Finalizer(终结器):负责调用对象的finalize()方法。
  4. Reference Handler :和GC、引用相关的线程。该线程是有着最高优先级的守护线程,排队待处理的References。GC创建一个简单的待处理引用链接列表,该线程将它们快速添加到适当的队列中,并通知ReferenceQueue监听器。
  5. Attach Listener(附加监听器):在目标JVM上动态附加一个监听器线程,在第一次附加请求时启动。该线程实际上允许另一个进程注入线程在运行的JVM中查询有关JVM运行的某些详细信息,例如调试、IDE debug等。
  6. DestroyJavaVM:该线程在程序退出时卸载JVM,大多情况下处于等待状态。




参考资料: 1. 慕课网课;2. https://stackoverflow.com/questions/19427339/jvm-core-threads
发布了72 篇原创文章 · 获赞 110 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/LIZHONGPING00/article/details/103755887