多线程-同步锁相关文章
----synchronized原理(锁关键字)
----ReentrantLock实现原理(可重入锁 )
----Volatile关键字原理
----CAS原理详解
Volatile
如果主内存 count 变量发生修改之后,线程工作内存中的值由于己经加载,不会产生对应的
变化,所以计算出来的结果会和预期不一样,对于 volatile 修饰的变量,jvm 虚拟机只是保证从主内存加载到线程工作内存的值是最新的
Volatile 是如何来保证可见性?
内存可见性(Memory Visibility):所有线程都能看到共享内存的最新状态
lock 前缀的指令在多核处理器下会引发了两件事情:
- 将当前处理器缓存行的数据会写回到系统内存
- 这个写回内存的操作会引起在其他 CPU 里存了该内存地址的数据无效。
(1)Java变量的读写
Java通过几种原子操作完成工作内存和主内存的交互:
- lock:作用于主内存,把变量标识为线程独占状态。
- unlock:作用于主内存,解除独占状态。
- read:作用主内存,把一个变量的值从主内存传输到线程的工作内存。
- load:作用于工作内存,把read操作传过来的变量值放入工作内存的变量副本中。
- use:作用工作内存,把工作内存当中的一个变量值传给执行引擎。
- assign:作用工作内存,把一个从执行引擎接收到的值赋值给工作内存的变量。
- store:作用于工作内存的变量,把工作内存的一个变量的值传送到主内存中。
- write:作用于主内存的变量,把store操作传来的变量的值放入主内存的变量中。
(2)volatile的特殊规则
- read、load、use动作必须连续出现。
- ssign、store、write动作必须连续出现
- 每次读取前必须先从主内存刷新最新的值
- 每次写入后必须立即同步回主内存当中
(3)执行流程
- 如果对声明了 volatile 变量进行写操作,JVM 就会向处理器发送一条Lock 前缀的指令,将这个变量所在缓存行的数据写回到系统内存
- 为了保证各个处理器的缓存是一致的,就会实现缓存一致性协议,每个处理器通过嗅探在总线上传播的数据来检杳自己缓存的值是不是过期了,当处理器发现自己缓存行对应的内存地址被修改,就会将当前处理器的缓存行设置成无效状态,
- 当处理器要对这个数据进行修改操作的时候,会强制重新从系统内存里把数据读到处理器缓存里。
(4)Volatile 的内存屏障
为了实现 volatile 的语义,JMM 在编译器和处理器层面限制指令重排序。
JMM 的内存屏障插入策略是保守策略:
- 在每个volatile写操作的前面插入一个StoreStore屏障。
- 在每个volatile写操作的后面插入一个StoreLoad屏障。
- 在每个volatile读操作的后面插入一个LoadLoad屏障。
- 在每个volatile读操作的后面插入一个LoadStore屏障。
多线程-同步锁相关文章
----synchronized原理(锁关键字)
----ReentrantLock实现原理(可重入锁 )
----Volatile关键字原理
----CAS原理详解