1、Java内存模型
1.1 主内存和工作内存
Java线程<->工作内存<->内存交互<->主内存
1.2 内存间交互操作
1)lock
2)unlock
3)read
4)load
5)use
6)assign
7)store
8)write
1.3 对于volatile型变量的特殊规则
volatile型变量的两种特性:
1)保证此变量对所有线程的可见性:当一个线程修改了此变量,新值对其他线程是立即得知的。
2)禁止指令重排序优化:对volatile变量增加一个内存屏障,不能把后面的指令重排到内存屏障之前。
由于java运算并非原子操作,导致volatile在并发下是不安全的。
在符合以下两个条件时可以保证并发安全。
1)运算结果并不依赖变量的当前值,或者能够确保只有单一的线程修改变量的值。
2)变量不需要与其他的状态变量共同参考不变约束。
1.4 对于long和double型变量的特殊规则
对于64位的数据类型(long和double),读写操作划分为两次32位的操作来进行。所以long和double是非原子性协定。
1.5 原子性、可见性与有序性
1)原子性:变量操作是原子性的。如果需要更大范围的原子性,lock和unlock来保证,体现的是synchronized关键字
2)可见性:通过变量修改后将新值同步回主内存。读取变量前从主内存刷新来实现的。volitile、synchronized和final都能实现可见性。
3)有序性:本线程所有操作都是有序的;其他线程所有操作都是无序的。volitile通过禁止指令重排来实现有序性。synchronized通过变量lock来实现。