我希望有一个可以从不同线程读取/写入的标志,而不会出现任何脏值问题。是否足以使其静态挥发?
static volatile boolean flag;
答案 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
*类。