JUC-15-线程和进程总结

JUC-15-线程和进程总结

1. 进程和线程

根本区别:进程操作系统资源分配的基本单位,而线程任务调度和执行的基本单位

1.1 进程

  • 一个在内存中应用的程序,每个进程都有自己独立的一块内存空间,一个进程可以有多个线程,比如在Windows系统中,一个运行的xx.exe就是一个进程。

mark

1.2 线程

  • 线程也叫做轻量级进程,在一个进程中可以创建多个线程。(进程中的一个执行单元,一个进程至少有一个线程,一个进程可以运行多个线程,多个线程可共享数据。)
  • 与进程不同的是同类的多个线程共享进程的堆和方法区(JDK1.8之后是元空间)资源,每个线程有自己的程序计数器,虚拟机栈和本地方法栈。所以系统在产生一个线程,或是在各个线程之间作切换工作时,负担要比进程小得多,也正因为如此,线程也被称为轻量级进程。

1.3 进程和线程区别总结

  • 根本区别:进程是操作系统资源分配的基本单位,而线程是处理器任务调度和执行的基本单位
  • 资源开销:每个进程都有独立的代码和数据空间(程序上下文),程序之间的切换会有较大的开销;线程可以看做轻量级的进程,同一类线程共享代码和数据空间,每个线程都有自己独立的运行栈和程序计数器(PC),线程之间切换的开销小。
  • 包含关系:如果一个进程内有多个线程,则执行过程不是一条线的,而是多条线(线程)共同完成的;线程是进程的一部分,所以线程也被称为轻权进程或者轻量级进程。
  • 内存分配:同一个进程的线程共享本进程的地址空间和资源,而进程之间的地址空间和资源是相互独立的。
  • 影响关系:一个进程崩溃后,在保护模式下不会对其他进程产生影响,但是一个线程崩溃整个进程都死掉。所以多进程要比多线程健壮。
  • 执行过程:每个独立的进程都有程序运行的入口,执行顺序和程序出口。但是线程不能单独执行,必须依存在应用程序之中,由引用程序提供多个线程的执行控制。

2. 从 JVM 角度说进程和线程之间的关系(重要)

下图是 Java 内存区域,通过下图我们从 JVM 的角度来说一下线程和进程之间的关系。

mark

从上图可以明显的看出:

  • 一个进程中可以有多个线程
  • 多个线程共享进程的堆和方法区
  • 但是每个线程有自己独立的程序计数器,虚拟机栈和本地方法栈

2.2 程序计数器为什么是私有的?

程序计数器主要有下面两个作用:

  1. 字节码解释器通过改变程序计数器来依次读取指令,从而实现代码的流程控制,如:顺序执行,选择,循环,异常处理。
  2. 多线程的场景下,程序计数器用于记录当前线程执行的位置,从而当线程被切换回来的时候能够知道该线程上次运行到哪里了。

需要注意的是,如果运行的是native方法,那么程序计数器记录的是undefined地址,只有执行java代码才能知道下一条指令的地址。

所以,程序计数器的私有主要是为了线程切换后能够恢复到正确的执行位置

2.3 虚拟机栈和本地方法栈为什么是私有的?

  • 虚拟机栈: 每个java方法在执行的同时会创建一个栈帧用于存储局部变量表,操作数栈,常量池的引用,方法返回地址。从方法调用直至执行完成的过程,对应着一个栈帧在java虚拟机栈中入栈和出栈的过程。
  • 本地方法栈:和虚拟机栈所发挥的作用非常相似,区别是: 虚拟机栈为虚拟机执行 Java 方法 (也就是字节码)服务,而本地方法栈则为虚拟机使用到的 Native 方法服务。 在 HotSpot 虚拟机中和 Java 虚拟机栈合二为一。

所以,为了保证线程中的局部变量不被别的线程访问到,虚拟机栈和本地方法栈是线程私有的。

2.4 一句话了解堆和方法区

  • 堆和方法区是所有线程共享的资源,其中堆是进程中最大的一块内存,主要用于存放新创建的对象(所有对象都在这里分配内存),
  • 方法区主要存放已被加载的类信息常量静态变量(常量和静态变量统称为常量池),即时编译后的代码数据

3. 多线程和多进程的区别

  • 多进程:操作系统中同时运行的多个程序
  • 多线程:在同一个进程中同时运行的多个任务。

举个例子,多线程下载软件,可以同时运行多个线程,但是通过程序运行的结果发现,每一次结果都不一致。 因为多线程存在一个特性:随机性。造成的原因:CPU在瞬间不断切换去处理各个线程而导致的,可以理解成多个线程在抢CPU资源。

多线程提高CPU使用率

mark

注意的是:

  • 多线程并不能提高运行速度,但是可以提高运行效率,因为让CPU的使用率更高
  • 但是如果多线程有安全访问问题或者出现频繁的上下文切换的时候,运行的速率可能反而会降低。

4. Java中的多线程

  • Java程序中的线程
    • main线程
    • GC(垃圾回收线程)(是一个守护线程)
  • 在 Java 中,当我们启动 main 函数时其实就是启动了一个 JVM 的进程,而 main 函数所在的线程就是这个进程中的一个线程,也称主线程。
  • Java支持多线程,当Java程序执行main方法的时候,就是在执行一个名字叫做main的线程,可以在main方法执行时,开启多个线程A,B,C,多个线程 main,A,B,C同时执行,相互抢夺CPU
  • Thread类是java.lang包下的一个常用类,每一个Thread类的对象,都代表一个处理某种状态的线程。
打赏
  • 版权声明: 本博客所有文章除特别声明外,均采用 Apache License 2.0 许可协议。转载请注明出处!
  • © 2019-2022 Zhuuu
  • PV: UV:

请我喝杯咖啡吧~

支付宝
微信