标签:java
volatile变量具有两种特性:
保证此变量对所有线程的可见性,注意:java里的运算不是原子操作,导致volatile变量在并发下存在不一致的问题。
使用规则要求
a. 运算结果并不依赖变量的当前值,或者能够确保只有单一的线程修改变量的值。
b. 变量不需要与其他的状态变量共同参与不变约束。
禁止指令重排序优化
其他说明:
Java内存模型中定义以下八种操作(具有原子性)完成:
1.lock(锁定):作用于主内存的变量,它把一个变量标识为一条线程独占的状态。
2.unlock(解锁):作用于主内存的变量,它把一个处于锁定状态的变量释放出来,释放后的变量才可以被其他线程锁定。
3.read(读取):作用于主内存的变量,它把一个变量的值从主内存传输到线程的工作内存中,以便随后的load动作使用。
4.load(载入):作用于工作内存的变量,它把read操作从内存中得到的变量值放入工作内存的变量副本中。
5.use(使用):作用于工作内存的变量,它把工作内存中的变量的值传递给执行引擎,每当虚拟机遇到一个需要使用到变量的值的字节码指令时将会执行这个操作。
6.assign(赋值):作用于工作内存的变量,它把一个从执行引擎接收到的值赋值给工作内存的变量,每当虚拟机遇到一个给变量赋值的指令码指令时执行这个操作。
7.store(存储):作用于工作内存的变量,它把工作内存中一个变量的值传递到主内存中,以便随后的write操作使用。
8.write(写入):作用于工作内存的变量,它把store操作从工作内存中得到的变量的值放入主内存的变量中。
volatile变量促使变量操作具有关联性,即load和use动作相关联,assign和store、write动作相关联,并且必须连续出现,而动作关联规则保证了变量不会被指令重排序优化。
long和double的非原子性协议:允许虚拟机实现选择可以不保证64位数据类型的load、store、read和write这四个操作的原子性(把64位的读写操作划分为两次32位的操作进行)。在实际开发中,各个平台的商用虚拟机还是把它们作为原子操作来对待,所以不需要把它们专门声明为volatile。
衡量并发安全问题的时候不要受到时间顺序的干扰,一切必须以先行发生原则为准。
标签:java
原文地址:http://6444407.blog.51cto.com/6434407/1616050