1、volatile的特性
- 可见性:对一个volatile变量的读,总是能看到任意线程对这个volatile变量最后的写入。
- 原子性:对任意单个volatile变量的读/写具有原子性,但类似于volatile++这种复合操作不具有原子性(基于这我们会认为volatile不具有原子性)。而锁的互斥执行的特性可以确保对整个临界区代码的执行具有原子性。
- 有序性:对volatile修饰的变量的读写操作前后加上各种特定的内存屏障来禁止指令重排序来保障有序性。
2、volatile写-读的内存语义
- 当写一个volatile变量时,JMM会把该线程对应的本地内存中的共享变量刷新到主内存。
- 当读一个volatile变量时,JMM会把该线程对应的本地内存置为无效,线程接下来将从主内存中读取共享变量。
3、volatile可见性实现原理
- JMM内存交互层面实现
- volatile修饰的变量的read、load、use操作和assign、store、write必须时连续的,即修改后必须立即同步回主内存,使用时必须从主内存刷新,由此保障volatile变量对多线程的可见性。
- 硬件层面实现
- 通过Lock前缀指令,会锁定变量缓存行区域并写回主内存,这个操作称为"缓存锁定",缓存一致性机制会阻止同时修改被两个以上处理器缓存的内存区域数据。一个处理器的缓存回写到主内存会导致其他处理器的缓存无效。
4、指令重排序
java语言规范规定JVM线程内部维持顺序化语义。即只要程序的最终结果与它顺序化情况的结果相等,那么指令的执行顺序可以与代码顺序不一致,此过程叫指令的重排序。
指令重排序的意义:JVM能根据处理器特性(CPU多级缓存、多核处理器等)适当的对机器指令进行重排序,使机器指令