Java:有没有正确的方法来使用静态volatile变量?

时间:2012-11-14 08:04:24

标签: java concurrency

我希望有一个可以从不同线程读取/写入的标志,而不会出现任何脏值问题。是否足以使其静态挥发?

static volatile boolean flag;

2 个答案:

答案 0 :(得分:5)

不,如果您需要这样的动作,这还不够:

volatile int v = 0;

Thread 1:
v++;

Thread 2:
v--;

理想情况下,当你执行上面的代码时你想要v = 0,但这就是真正发生的事情(复合动作):

Thread 1:
r1 = v;
r2 = r1 + 1;
v = r2;

Thread 2:
r3 = v;
r4 = r3 - 1;
v = r4;

两个线程分别给出1和-1的值。资料来源:Volatile Does Not Mean Atomic!

如果在多线程场景中需要保证一致的结果,则应该使用Java中的Atomic类,如@ Eng.Fouad所指出的那样。

对于布尔值,比较和设置对AtomicBoolean类比使用volatile更有帮助。

答案 1 :(得分:3)

这很诱人,但要避免这样的代码。

在一个简单的场景中,这似乎有效,因为boolean不允许任何数学运算(你只能为它赋值)。但你很少有简单的案例。最终,你需要

if(flag) {
    flag = false;
}

此代码有时会中断。因此,正如其他答案所建议的那样,您应该使用java.util.concurrent.Atomic *类。