硬件的效率与一致性
由于计算机的处理器速度与内存的读取速度相差很大,所以为了解决处理器与内存之间的速度矛盾,计算机系统主要做了两个方面的优化:一是在处理器和内存之间增加一层读写速度尽可能接近处理器运算速度的高速缓存区来作为处理器与内存之间的缓冲,二是为了使处理器内的运算单元能尽量被充分利用,处理器会对代码进行乱序执行优化。
高速缓冲区的工作原理:将运算需要用到的数据复制到高速缓冲区中,让运算快速执行,当运算结束后再把结果同步回主内存中,这样处理器就不用等待缓慢的内存读写了。
乱序执行的工作原理:处理器为了充分利用运算单元,会对输入的代码进行乱序执行,并将乱序执行后的计算结果进行重组,保证乱序执行的结果与顺序执行的结果一致,但并不保证程序中的各个语句的执行顺序与代码顺序一致。
缓存一致性:在多处理器系统中,每个处理器都有自己的高速缓冲区,它们又共享同一主内存,所以当有多个处理器的运算任务都涉及同一主内存时,可能会导致各自缓存的数据不一致,所以需要在缓存与主内存的同步问题上需要加入一层协议来解决缓存不一致性的问题,而Java内存模型就是约定这种协议的抽象模型。
处理器、高速缓存、主内存间的关系主内存与工作内存
Java内存模型并没有限制系统使用寄存器或高速缓存来与主内存进行交互,也没有限制处理器调整代码执行顺序的优化。Java内存模型中规定了所有变量都必须存放在主内存中,每个线程都有自己的工作内存(类比于高速缓存),工作内存中主要保存了被该线程使用到的变量的主内存副本拷贝,线程对变量的所有读写操作都必须执行在工作内存中,不能直接读写主内存中的变量,同时线程间的变量传递需经过主内存来完成。
线程、工作内存、主内存的关系主内存与工作内存的交互
Java内存模型定义了主内存与工作内存之间的交互协议,也就是说一个变量如何从主内存拷贝到工作内存中,以及如何从工作内存中把变量同步回主内存中,主要定义了一下8种操作来完成这些实现细节:
lock(锁定):把一个变量标记为一条线程独占的状态(作用于主内存);
unlock(解锁):把一个变量从锁定状态中解除,以便被其它线程访问(作用于主内存)
read(读取):把一个变量值从主内存读取到工作内存中,以便后续的load操作(作用于主内存);
load(载入):把从主内存中读取的变量值放入工作内存的变量副本中(作用于工作内存);
use(使用):把工作内存的变量传递给线程的执行引擎处理(作用于工作内存);
assign(赋值):接收线程的执行引擎处理完成的结果并赋值给工作内存的变量副本(作用于工作内存);
store(存储):把工作内存中的变量值传递到主内存中,以便后续的write操作(作用于工作内存);
write(写入):把从工作内存中传递过来的变量值放入主内存的变量中(作用于主内存);
(1)read和load、store和write两组必须是顺序执行的,但是非连续执行;
(2)什么情况下会触发变量从工作内存同步回主内存:assign操作执行后必须把变量从工作内存中同步会主内存;对一个变量执行unlock操作之前,必须把变量从工作内存中同步会主内存;
参考
《深入理解Java虚拟机》第2版 第12章 Java内存模型与线程
网友评论