auto commit

This commit is contained in:
CyC2018 2018-03-13 10:35:41 +08:00
parent b7bd828b16
commit 97ca9ab198

View File

@ -20,6 +20,9 @@
* [1. 阻塞](#1-阻塞)
* [2. 中断](#2-中断)
* [线程状态转换](#线程状态转换)
* [volatile](#volatile)
* [1. 内存可见性](#1-内存可见性)
* [2. 禁止指令重排](#2-禁止指令重排)
* [内存模型](#内存模型)
* [1. 硬件的效率与一致性](#1-硬件的效率与一致性)
* [2. Java 内存模型](#2-java-内存模型)
@ -423,6 +426,26 @@ interrupted() 方法在检查完中断状态之后会清除中断状态,这样
- LockSupport.parkNanos() 方法
- LockSupport.parkUntil() 方法
# volatile
保证了内存可见性和禁止指令重排,没法保证原子性。
## 1. 内存可见性
普通共享变量被修改之后,什么时候被写入主存是不确定的。
volatile 关键字会保证每次修改共享变量之后该值会立即更新到内存中,并且在读取时会从内存中读取值。
synchronized 和 Lock 也能够保证内存可见性。它们能保证同一时刻只有一个线程获取锁然后执行同步代码,并且在释放锁之前会将对变量的修改刷新到主存当中。不过只有对共享变量的 set() 和 get() 方法都加上 synchronized 才能保证可见性,如果只有 set() 方法加了 synchronized那么 get() 方法并不能保证会从内存中读取最新的数据。
## 2. 禁止指令重排
在 Java 内存模型中,允许编译器和处理器对指令进行重排序,重排序过程不会影响到单线程程序的执行,却会影响到多线程并发执行的正确性。
volatile 关键字通过添加内存屏障的方式来进制指令重排,即重排序时不能把后面的指令放到内存屏障之前。
可以通过 synchronized 和 Lock 来保证有序性,它们保证每个时刻只有一个线程执行同步代码,相当于是让线程顺序执行同步代码,自然就保证了有序性。
# 内存模型
## 1. 硬件的效率与一致性