【Java虚拟机】Java内存模型与线程

版权声明:转载请注明出处: https://blog.csdn.net/qq_21687635/article/details/84071871

Java内存模型

  • 所有的变量都存储在主内存中。
  • 每条线程都有自己的工作内存。
  • 线程的工作内存保存了被该线程使用到的变量的主内存副本拷贝。
  • 线程对变量的所有操作都必须在工作内存中进行,不能直接读写主内存的变量

线程、主内存、工作内存三者的交互关系如下图所示:

在这里插入图片描述

内存间交互操作

  • lock:作用于主内存的变量,它把一个变量标识为一条线程独占的状态。
  • unlock:作用于主内存的变量,它把一个处于锁定状态的变量释放出来,释放后的变量才可以被其他线程锁定。
  • read:作用于主内存的变量,它把一个变量的值从主内存传输到线程的工作内存中,以便随后的load动作使用。
  • load:作用于工作内存的变量,它把read操作从主内存中得到的变量值放入工作内存的变量副本中。
  • use:作用于工作内存的变量,它把工作内存中一个变量的值传递给执行引擎,每当虚拟机遇到一个需要使用到变量的值的字节码指令时将会执行这个操作。
  • assign:作用于工作内存的变量,它把一个从执行引擎接收到的值赋给工作内存的变量,每当虚拟机遇到一个给变量赋值的字节码指令时执行这个操作。
  • store:作用于工作内存的变量,它把工作内存中一个变量的值传送到主内存中,以便随后的write操作使用。
  • write:作用于主内粗你的变量,它把store操作从工作内存中得到的变量的值放入主内存的变量中。

volatile关键字

  • 可见性:使用前必须先从主内存刷新最新的值,修改变量之后必须立刻同步会主内存中
  • 禁止指令重排序优化

Java与线程

内核实现

内核线程(Kernel-Level Thread,KLT)直接由操作系统内核支持的线程,由内核来完成线程切换,内核通过操纵调度器对线程进行调度,并负责将线程的任务映射到各个处理器上。

程序一般使用内核线程的一种高级接口——轻量级进程(Light Weight Process,LWP),每个轻量级进程都有一个内核线程支持。

轻量级进程与内核线程之间的关系如下图所示:
在这里插入图片描述

使用用户线程实现

用户线程的建立、同步、销毁和调度完全在用户态中完成,不需要内核的帮助。

所有的线程操作都需要用户程序自己处理。线程的创建、切换和调度都是需要考虑的问题,而且由于操作系统只把处理器资源分配的进程,那诸如“阻塞如何处理”、“多处理器系统中如何将线程映射到其他处理器”这类问题解决起来将会异常困难,甚至不可能完成。

进程与用户线程之间的关系如下图所示:
在这里插入图片描述

使用用户线程加轻量级进程混合实现

这种混合实现下,既存在用户线程,也存在轻量级进程。用户线程还是完全建立在用户空间中,轻量级进程则作为用户线程和内核线程之间的桥梁。

用户线程与轻量级进程之间的关系如下图所示:
在这里插入图片描述

Java线程的实现

不同的平台,采用不同的线程模型。

Windows版和linux版都是使用内核实现的。

Solaris平台,支持内核实现的内线程模型和用户线程加轻量级线程的线程模型,可以根据参数来选择一种线程模型。

Java线程调度

  • 协同式线程调度:线程的执行时间由线程本身来控制,线程把自己的工作执行完了之后,要主动通知系统切换到另一个线程上。
  • 抢占式线程调度:每个线程由系统来分配时间,线程的切换不由线程本身决定。

Java采用的是抢占式调度。

状态转换

Java语言定义了5种线程状态,在任意一个时间点,一个线程只能有且只有其中的一种状态

  1. 新建(New):创建后尚未启动的线程处于这种状态。
  2. 运行(Runable):Runable包括了操作系统线程状态中的Running和Ready,也就是处于此状态的线程有可能正在执行,也有可能正在等待CPU为它分配执行时间
  3. 无限期等待(Waiting):处于这种状态的线程不会分配CPU时间,他们要等待被其他线程显示地唤醒。比如:object.wait()、thread.join()
  4. 期限等待(Timed Waiting):处于这种状态的线程也不会分配CPU时间,不过无需等待被其他线程显示地唤醒,在一定时间之后它们会有系统自动唤醒。比如:thread.sleep(millis)、object.wait(timeout)、thread.join(millis)
  5. 阻塞(blocked):线程被阻塞了,等待进入同步区域的时候,线程将进入这种状态。
  6. 结束(Terminated):已终止线程的线程状态,线程已经结束执行

线程状态状态如下图所示:
在这里插入图片描述

参考

  1. 深入理解Java虚拟机[书籍]

猜你喜欢

转载自blog.csdn.net/qq_21687635/article/details/84071871