主要作用:是变量在多个线程中可见,修饰变量,解决一写多读的问题。
轻量级的synchronized,不会造成阻塞。性能比synchronized好得多,不支持原子性操作。为了保证原子性要使用atomic对象,只能保证本身方法的原子性,不能保证多次操作的原子性。(解决方法synchronized)
原理:当把变量声明为volatile类型后,编译器与运行时都会注意到这个变量是共享的,因此不会将变量上的操作与其他内存操作一起重排序。不会被缓存在寄存器或者对其他处理器不可见的地方,因此读取volatile类型的变量时总会返回最新写入得值。
缺点:如果在代码中使用volatile变量来控制状态的可见性,通常比使用锁的代码更脆弱,也更难理解。就加锁机制可以确保可见性又可以确保原子性。
1 何时使用volatile关键字?
仅当volatile变量能简化代码的实现以及对同步策略的验证时,才应该使用它们。如果在验证正确性时需要对可见性进行复杂的判断,那么就不要使用volatile变量。volatile变量的正确使用方式包括:确保它们自身状态的可见性,确保它们所引用对象的状态的可见性,以及标识一些重要的程序生命周期事件的发生(例如,初始化或关闭)
2 使用volatile关键字需要满足的三个条件
1.对变量的写入操作不依赖变量的当前值,或者你能确保只有单个线程更新变量的值。
2.该变量不会与其他状态变量一起纳入不变性条件中。
3.在访问变量时不需要加锁。
典型用法:检查某个状态标记判断是否退出循环。
eg:
/**
线程试图通过类似于数绵羊的传统方法进入休眠状态。为了使这个示例能正确执行,asleep必须为volatile变量。否则,当asleep被另一个线程修改时,执行判断的线程却发现不了。
**/
volatile boolean asleeep;
...
while(!asleep)
countSomeSheep();
网友评论