http://www.ibm.com/developerworks/cn/java/j-jtp06197.html 一文笔记
在java中,为了提高性能,线程一般把变量从内存中备份一个副本到寄存器。volatile 关键字意思是易失性,明确表示
一个变量是会被多线程访问的,每个线程在每次读取都要从内存读取原始副本的值,而不是缓存在寄存器中的值。每次修改
都是把值写回到内存中。
Java语言包含两种内在的同步机制:同步块(或方法)和 volatile 变量。
synchronized锁提供了两种主要特性:
互斥(mutual exclusion) 和
可见性(visibility)。互斥即一次只允许一个线程持有某个特定的锁,因此可使用该特性实现对共享数据的协调访问协议,这样,一次就只有一个线程能够使用该共享数据。可见性必须确保释放锁之前对共享数据做出的更改对于随后获得该锁的另一个线程是可见的。 否则,线程看到的共享变量可能是修改前的值或不一致的值,引发严重问题。
volatile能够实现上述可见性,因为线程每次都是读取原始版本的值,前一个线程的修改对后续线程来说是可见的。但volatile不能确保互斥。
volatile适用的原则:
- 对变量的写操作不依赖于当前值。
- 该变量没有包含在具有其他变量的不变式中。
所以volatile不能用作计数器,因为计数器的自增是一个读-增-写的过程,不是原子操作,在volatile不确保互斥的情况下,结果不准确。
不变式的意思是一个需要不变的规律,如起始要小于等于结束。上述2点简单来说:即变量真正独立于其他变量和自己以前的值 , 在这些
情况下可以使用
volatile
代替
synchronized
来简化代码。
volatile由于不阻塞线程,在性能一般比synchronized表现更好。
适用volatile的几个场景:
1、状态标志 比如标示服务启动或停止。
2、独立观察 定期 “发布” 观察结果供程序内部使用,
3、
结合使用 volatile 和 synchronized 实现 “开销较低的读-写锁”
@ThreadSafe
public class CheesyCounter {
private volatile int value;
// 使用volatile实现可见性,开销低
public int getValue() { return value; }
// 使用synchronized实现互斥
public synchronized int increment() {
return value++;
}
}
posted on 2011-04-08 16:28
liucs 阅读(364)
评论(0) 编辑 收藏 所属分类:
Java