JVM之JMM详解(卷一)

1 序言:

   在讲解Java的内存模型之前,我们可以看看物理机在遇到并发问题时所想出的处理方案(物理机和Java虚拟机在解决并发问题有不少相似的地方,具有很大的参考价值)。本章旨在剖析Java的内存模型以及让读者明白Java并发编程里不知其所以然的地方。(推荐书籍《Java并发编程艺术》《深入理解Java虚拟机 第二版》) 

2 物理机并发解决方案

  2.1 处理器,高速缓存,主内存间的交互图

image
讲解:“让计算机并发执行若干个运算任务”与“更充分地利用计算机处理器的效能”之间因果关系,看起来顺理成章,实际上他们之间的关心并没有想象中的那么简单。由于计算机绝大多数的运算任务肯定不能交给处理器来负责,至少要跟内存打交道。所以I/0流就是计算机其中一种限制,所以为了防止消耗过多的时间在数据读取方面,所以如图”高速缓存“cache就出现了,计算机将要处理的数据先从主内存读到缓存区中。在这个过程中我们不难发现每个处理器都有自己的高速缓存区,那么从主内存读来的数据如何保证正确性了。这时缓存一致性协议就出现了。
   数据问题解决了那如何提高物理机的性能?聪明的人总有办法,那就是让处理器内部的运算单元能尽量被充分利用。如何充分利用了? 那就是对输入的代码进行乱序执行优化,处理器会在计算之后将乱序执行的结果重组,保证该结果与顺序执行的结果是一致的,但不保证程序中各个语句计算的先后顺序与输入代码中的顺序一致。(类似于Java内存模型的指令重排)。 

3Java的内存模型

目的:屏蔽掉各种硬件和操作系统的内存访问差异,以实现让Java程序在各种平台下都能达到一致的内存访问效果。即一次编译到处运行。

3.1 工作内存和主内存

如图 image

内存的交互操作

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

从上图可知线程之间的通信是如何进行的?

如图 image
从图中可以看出线程A和线程B的通信实质就是线程A把它本地内存的值写到主内存中,线程B去值不是从本地内存中取而是从主内存中去取得值,这样间接的实现了线程A与线程B之间的通信。

从上述的通信图,我们不难象到Java多线程的一个非常重要的关键字volatile,下面我们就一起看看volatile的工作原理吧!(卷二)


猜你喜欢

转载自blog.51cto.com/12666319/2311658
今日推荐