正确使用volatile
在jdk5修正了volatile的语义后,volatile作为一种轻量级的同步策略就得到了大量的使用。volatile的严格定义参考jvm spec,这里只从volatile能做什么,和不能用来做什么出发做个探讨。
volatile可以用来做什么?
1)状态标志,模拟控制机制。常见用途如控制线程是否停止:
private volatile boolean stopped;
public void close(){
stopped=true;
}
public void run(){
while(!stopped){
//do something
}
}
前提是do something中不会有阻塞调用之类。volatile保证stopped变量的可见性,run方法中读取stopped变量总是main memory中的最新值。
2)安全发布,如修复DLC问题。
private volatile IoBufferAllocator instance;
public IoBufferAllocator getInsntace(){
if(instance==null){
synchronized (IoBufferAllocator.class) {
if(instance==null)
instance=new IoBufferAllocator();
}
}
return instance;
}
3)开销较低的读写锁
public class CheesyCounter {
private volatile int value;
public int getValue() { return value; }
public synchronized int increment() {
return value++;
}
}
synchronized保证更新的原子性,volatile保证线程间的可见性。
volatile不能用于做什么?
1)不能用于做计数器
public class CheesyCounter {
private volatile int value;
public int getValue() { return value; }
public int increment() {
return value++;
}
}
因为value++其实是有三个操作组成的:读取、修改、写入,volatile不能保证这个序列是原子的。对value的修改操作依赖于value的最新值。解决这个问题的方法可以将increment方法同步,或者使用AtomicInteger原子类。
2)与其他变量构成不变式
一个典型的例子是定义一个数据范围,需要保证约束lower< upper。
public class NumberRange {
private volatile int lower, upper;
public int getLower() { return lower; }
public int getUpper() { return upper; }
public void setLower(int value) {
if (value > upper)
throw new IllegalArgumentException();
lower = value;
}
public void setUpper(int value) {
if (value < lower)
throw new IllegalArgumentException();
upper = value;
}
}
尽管讲lower和upper声明为volatile,但是setLower和setUpper并不是线程安全方法。假设初始状态为(0,5),同时调用setLower(4)和setUpper(3),两个线程交叉进行,最后结果可能是(4,3),违反了约束条件。修改这个问题的办法就是将setLower和setUpper同步:
public class NumberRange {
private volatile int lower, upper;
public int getLower() { return lower; }
public int getUpper() { return upper; }
public synchronized void setLower(int value) {
if (value > upper)
throw new IllegalArgumentException();
lower = value;
}
public synchronized void setUpper(int value) {
if (value < lower)
throw new IllegalArgumentException();
upper = value;
}
}
分享到:
相关推荐
详细说明 并举例说明了VOlatile的作用及用法,特别是嵌入式程序员要注意的
一般对于volatile的解释是这样的:将变量定义为volatile可以防止编译器对变量进行优化,每次均从内存中访问变量,而不是寄存器。既然让编译器优化可以提高访问速度,那为什么又要不用它以及什么时候不用它?其实主要...
C语言中关键字volatile的作用,使用说明和例子
const,extern,static,volatile的使用
一般说来,volatile用在如下的几个地方: 1、中断服务程序中修改的供其它程序检测的变量需要加volatile; 2、多任务环境下各任务间共享的标志应该加volatile; 3、存储器映射的硬件寄存器通常也要加volatile说明,...
const和volatile分析 这个分析得很好 面试 找工作 必备的
volatile的用法讲解,讲得很详细,希望能帮助到大家
主要讲述java线程volatile关键字
C程序中volatile关键字的使用.方法及其例程介绍。
volatile与synchronized的区别,锁提供了两种主要特性:互斥(mutual exclusion) 和可见性(visibility)
本文给大家介绍了单片机C语言中volatile的作用。
讲述了volatile_unsigned_int地址映射的使用说明。
宏定义volatile的用法,希望和大家共同学习进步。
Java并发编程:volatile关键字解析
volatile变量的使用是区分c程序员和嵌入式系统程序员的最基本问题。不懂得volatile变量的内容将带来灾难。这个文档帮助你减少因此带来的bug。
static,const,volatile用法的解析,对三项中全局变量和局部变量的区分,volatile中介绍了其具体用法 和一些区别,bong有例子
extern_volatile等修饰符的用法
volatile 的字面含义是易变的,那么将一个变量指示为volatile 是什么意思呢?是告诉编 译器这个变量是易变的?事实上也是如此。在多任务、中断等环境下,变量可能被其他的任 务改变,而编译器无法发现,volatile ...
本文将深入分析在硬件层面上Inter处理器是如何实现Volatile的,通过深入分析能帮助我们正确的使用Volatile变量。
本篇文章主要介绍单片机中volatile定义的作用,感兴趣的朋友可以看看。