JMM
JMM (java memary model java内存模型)
一、CPU架构缓存一致性
现在计算机都加高级缓存,让运算速度加快,在运算过程中把某些变量放到高级缓存里面,等运算结束以后,再从高级缓存同步到内存中,这样避免IO读写过慢CPU的空闲。
加入高级缓存会带来问题,带来缓存一致性的问题,在多线程情况下,看不见已经修改的变量的值。最初的解决方案就是总线锁的方式,总线锁性能比较低,多个CPU出现竞争,有的cpu出现空闲等待。
现在的cpu是基于缓存一致性协议实现的内存模型。最出名的缓存一致性协议internet 的mesi,共享变量a在处理器都存在副本,如果变量被某一个处理器改了会发出信号告诉其他的CPU置成无效的。
1、缓存一致性协议
缓存一致性协议给缓存行(通常为64字节)定义了个状态,用来描述该缓存行是否被多处理器共享、是 否修改,缓存一致性协议最出名的是mesi。
独占:仅当前处理器拥有改缓存行
共享:多个处理器拥有该缓存行,每个处理器都没修改过缓存值。
修改:仅当前处理器拥有改缓存行,并且缓存行被修改过。
失效:缓存行被其它处理器修改过,不是最新的,就会变成失效状态,重新读取值。
二、CPU相关术语
内存屏障:Memory barriers 是一组处理器指令,用于实现对内存操作的顺序执行。
缓存行:Cache line 缓存中可以分配的最小存储单位
三、原子性、可见性、有序性
1、原子性:read、load、use、assign、store、write、lock、unlock 8个汇编指令。Monitorenter monitorexit。线程之间互不影响,不被中断。
2、可见性:一个线程操作的变量对其它线程可见
3、有序性:线程内都是有序的,线程内观察别的线程都是无序的。
四、JMM模型
1、工作内存中,线程A改了对线程B不可见。
2、JMM内存模型分析
Read 从主内存里读出来,load载入,作用于工作内存,从内存读的值放到工作变量里。User 作用于工作内存,把变量传递给执行引擎(cpu)。Assign 赋值,主要作用于工作内存。Store存储,主要作用于工作内存。Write 主要作用于主内存。
3、指令重排
编译器重排序:不改变单线程执行结果的前提,对语句执行顺序进行优化。
指令级并行重排序:采用并行技术ilp,多条指令的重叠执行。
内存系统得重排序:处理器使用缓存和读写缓存序列,使我们的加载存储操作是乱序执行的,as if serial单线程语义规则。
4、Happens-before
只是一个概念
5、内存屏障
1)阻止屏障两侧的指令重排序
2)强制把写缓存去/高速缓存区的脏数据写回主内存,让缓存中响应的数据失效。
在JSR规范中定义了4种内存屏障:
• LoadLoad屏障:(指令Load1; LoadLoad; Load2),在Load2及后续读取操作要读取的数据被访问前,保证Load1要读取的数据被读取完毕。
• LoadStore屏障:(指令Load1; LoadStore; Store2),在Store2及后续写入操作被刷出前,保证Load1要读取的数据被读取完毕
• StoreStore屏障:(指令Store1; StoreStore; Store2),在Store2及后续写入操作执行前,保证Store1 的写入操作对其它处理器可见
• StoreLoad屏障(比较常用):(指令Store1; StoreLoad; Load2),在Load2及后续所有读取操作执行前,保证Store1的写入对所有处理器可见。
Jdk源码地址
https://github.com/openjdk/jdk
看汇编时需要下载一个软件 hisdis 下载dll 放在jre下面的lib下面,下载jclasslib bytecode Viewer插件,通过这个插件可以看class的字节码。下载JITWatch 看汇编
6、Volatile
用StoreLoad 内存屏障,防止指令重排序。
五、可见性
1、加了volatile,有lock就总线嗅探,如果发生变化,使自己的变量失效,重新加载
2、单例的双重检索,这样写的好处是,延迟初始化来降低初始化类和创建对象的一个开销。
使用单例模式,如果没有加volatile,会有指令重排序,导致拿到的instance为空,而报错。
六、CAS
独占锁是一种悲观锁,synchronized就是一种悲观锁,会导致其它所有需要锁的线程挂起,等待持有锁的线程释放。
乐观锁是一种更加有效的锁,每次不加锁,而是假设没有冲突而去完成某项操作,如果因为冲突失败就重试,直到成功为止。
cmpxchg是汇编指令
作用:比较并交换操作数
2、问题:以下counter的输出小于20万,并且一般情况下小于20万。Counter的操作不具有原子性。
AtomicInteger 共享变量包装类。使变量变为原子性。
While自旋,直到成功为止。