请采用这个非常简单的例子:
volatile int globalVar = 1;
我的主题:
if (globalVar > 0) {
globalVar--;
}
现在,我必须决定使变量volatile变得足以防止竞争条件并使这个线程安全。
我知道递增和递减不是,但由于前面的条件,我不确定它是否不同。
我认为它仍然不安全,因为它可以按此顺序执行:
线程A检查条件。线程B检查条件。 线程A递增。线程B递增。
我是对的吗?
答案 0 :(得分:2)
你是对的。由于您声明的原因,它不是线程安全的。 volatile
确保两个线程都能看到变量的更新值,但不能保护多行代码。
答案 1 :(得分:1)
不,它不是线程安全的。 挥发性不保证原子性。操作如 我 - 不是原子的,所以宣称我不稳定并没有帮助。
int globalVar = 1;
lock.lock()
try{
if(globalVar > 0)
globalVar--;
}finally {
lock.unlock();
}
上面的代码可以使用,你不需要在这里声明golbalVar为volatile
因为
挥发性有两个保证:
1.可见性
2.重新排序
而
同步/锁定/解锁给予三个保证 1.Atomicity 2.可见性 3.Reordering
另外请记住,无论何时在多个线程之间共享Object,始终都可以访问它 任何同步动作同步/易失性读/写下的对象。
阅读JLS作者第17章的优秀文章。这是必读的 http://jeremymanson.blogspot.in/2008/11/what-volatile-means-in-java.html http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html
答案 2 :(得分:0)
要使代码线程安全,您需要在检查和修改周围添加synchronized
块。
可以做的事情的一个例子:
volatile Integer globalVar = 1;
然后在完成工作的方法中:
synchronized public void decrement(){
if(globalVar > 0)
globalVar--;
}
}
答案 3 :(得分:0)
volatile不保证原子性。你可以简单地添加一个同步块。
synchronized(this)
{
if (globalVar > 0) {
globalVar--;
}
}