多线程

  • 线程 程序 进程
  • 线程和进程的关系(JVM角度)
  • 程序计数器为什么私有
  • 虚拟机栈 本地方法栈为什么私有
  • 堆和方法区(元空间)
  • 线程的六种状态
  • 并发与并行

线程 程序 进程

程序:含有指令和数据的文件,被存储在磁盘或其他数据存储设备种,即程序是静态的代码
进程:程序的一次执行过程,是系统运行程序的基本单位,是动态的。系统运行一个程序就是一个进程从创建、运行到消亡的过程。一个进程就是一个执行中的程序,在计算机中一个指令接着一个的执行,同时每个进程还占有某些系统资源如CPU时间、内存空间、文件、输入输出设备的使用权等。即程序在执行时,会被操作系统载入内存中。
线程:比进程更小的执行单位。一个进程在执行过程中可以产生多个线程,同类的多个线程共享进程的堆和方法区(JDK1.8之后是元空间)资源,但每个线程都有自己的程序计数器、虚拟机栈和本地方法栈。所以系统在产生一个线程或在多个线程中切换工作时,负担比进程小得多,正因如此,线程被称为轻量级进程。⼀个 Java 程序的运⾏是 main 线程和多个其他线程同时运⾏。
线程和进程最大的不同在于:基本上各进程之间相互独立,线程不一定,同一进程中的线程之间相互影响。从另一个角度看,进程属于操作系统的范畴,主要是同一时间内,可以同时执行一个以上的程序,而线程则是在同一程序内几乎同时执行一个以上的程序段

线程和进程的关系(JVM角度)

多个java程序消费一个topic java程序由一个或多个_程序计数器


从上图可以看出:⼀个进程中可以有多个线程,多个线程共享进程的堆和⽅法区 (JDK1.8 之后的元空间)资源,但是每个线程有⾃⼰的程序计数器、虚拟机栈 和 本地⽅法栈。

程序计数器为什么私有

程序计数器主要有下⾯两个作⽤:

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

需要注意的是,如果执⾏的是 native ⽅法,那么程序计数器记录的是 undefined 地址,只有执⾏的是 Java 代码时程序计数器记录的才是下⼀条指令的地址。
所以,程序计数器私有主要是为了线程切换后能恢复到正确的执⾏位置。

虚拟机栈 本地方法栈为什么私有

  • 虚拟机栈: 每个 Java ⽅法在执⾏的同时会创建⼀个栈帧⽤于存储局部变量表、操作数栈、常量池引⽤等信息。从⽅法调⽤直⾄执⾏完成的过程,就对应着⼀个栈帧在 Java 虚拟机栈中⼊栈和出栈的过程。
  • 本地⽅法栈: 和虚拟机栈所发挥的作⽤⾮常相似,区别是: 虚拟机栈为虚拟机执⾏ Java⽅法 (也就是字节码)服务,⽽本地⽅法栈则为虚拟机使⽤到的 Native ⽅法服务。 在HotSpot 虚拟机中和 Java 虚拟机栈合⼆为⼀。

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

堆和方法区(元空间)

堆和⽅法区是所有线程共享的资源,其中堆是进程中最⼤的⼀块内存,主要⽤于存放新创建的对象 (所有对象都在这⾥分配内存)⽅法区主要⽤于存放已被加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

线程的六种状态

多个java程序消费一个topic java程序由一个或多个_多线程_02

多个java程序消费一个topic java程序由一个或多个_程序计数器_03

线程创建之后处于NEW状态,调用start()方法后处于READY状态,获得CPU时间片之后进入RUNNING状态。(Java系统将READY和RUNNING状态统称为RUNNABLE状态)。

并发与并行

  • 并发: 同⼀时间段,多个任务都在执⾏ (单位时间内不⼀定同时执⾏);
  • 并⾏: 单位时间内,多个任务同时执⾏。