1、为何演进,如何演进。
计算机在运行程序的时,每条指令都是在CPU中执行,在执行的过程中势必会涉及到数据的读写。
而程序运行的数据时存储在主内存中的,也就是我们常说的内存,那么此时就会有一个问题:
解决办法:
这样CPU不必与执行速度较之较慢的主内存打交道,而是和运行速度快的CPU高速缓存打交道,这样充分利用了CPU的高效性能。
———————————————————————————————————————————————————————
2、演进后导致了什么问题,如何解决的
硬件的演进使用了CPU高速缓存,这在单线程中的确是没问题的,但在多线程中便会导致缓存一致性的问题。
如i++;这段代码:
此时有两个线程都这样操作,那预期i的值应该是3。
两个线程并发操作,会导致如下结果:
———————————————————————————————————————————————————————
3、如何解决
加锁的方式通过独占来实现,只有一个CPU能执行,效率极为低下,不推荐使用。所以一般会采用缓存一致性协议来实现,【窥探技术+MESI协议】。
窥探技术:
MESI协议:
因JVM是硬件层次之上的,所以需要解决缓存一致性问题。
1、如何解决:通过volatile关键字。
2、volatile内存语意含义
volatile可以保证线程可见性且提供了一定的有序性,但是无法保证原子性。
在JVM底层volatile是采用内存屏障来实现的。
上面那段话,有两层语义
3、volatile原理
JVM底层是通过一个叫做内存屏障的东西来完成。
内存屏障,也叫做内存栅栏,是一组处理器指令,用于实现对内存操作的顺序限制。
下面是完成上述规要求的一些规则,在NO的地方就是需要用内存屏障来控制的。
也就是操作只要带有volatile,都需要内存屏障来控制。
读:Load,写:Store;再配合上图就很好记了。
原文:https://www.cnblogs.com/bzfsdr/p/12496280.html