Jas*_*n S 54 java concurrency atomic volatile
我已经查看了SO中的其他volatile和Atomicxxxx问题(包括这个),并阅读了java.util.current.atomic的描述,我对细微差别不太满意.
如果我在尝试使用volatile boolean和之间做出决定AtomicBoolean,除了AtomicBoolean提供的原子读取 - 修改 - 写入操作之外是否存在实际差异?(例如compareAndSet()和getAndSet())
假设我有
volatile boolean flag;
Run Code Online (Sandbox Code Playgroud)
然后一个或多个线程设置标志(但不清除它).如果我有一个线程读取标志,如果设置,执行操作,然后清除标志,是否volatile足够?
AtomicBoolean的成本是否高于volatile布尔值
volatile boolean似乎需要内存防护,AtomicBoolean似乎需要内存防护+根据java.util.current.atomic描述对CAS操作进行一些小锁定)我的直觉调用是使用AtomicBoolean并且是安全的,但我想了解是否有任何情况可以使用volatile boolean(例如,如果我有数千个实例,性能是一个问题).
biz*_*lop 72
之间的主要区别AtomicBoolean和volatile从实际的角度来看是,比较并设置操作不是原子与volatile变量.
volatile boolean b;
void foo() {
if( b ) {
//Here another thread might have already changed the value of b to false
b = false;
}
}
Run Code Online (Sandbox Code Playgroud)
但是看到所有并发写入都是幂等的并且您只从一个线程读取,这应该不是问题.
Cow*_*wan 19
我不确定我是否完全同意这里的其他答案; biziclop的回答是正确的,但我不确定除非我们知道更多细节,否则我们可以断定你是安全的.
在简单的情况下,交错可能如下所示:
Thread 1 (writer) Thread 2 (Writer) Thread 3 (Reader)
----------------- ----------------- -----------------
flag = true;
if (flag) {
flag = true;
flag = false;
doStuff();
Run Code Online (Sandbox Code Playgroud)
这可能是罚款(第二组flag到true无所谓,因为doStuff()仍然可能会看到任何线程2个需要做的事情.
但是,如果您反转线程3的顺序:
Thread 1 (writer) Thread 2 (Writer) Thread 3 (Reader)
----------------- ----------------- -----------------
flag = true;
if (flag) {
doStuff();
flag = true;
flag = false;
Run Code Online (Sandbox Code Playgroud)
然后线程2的更新可能会丢失.
当然,你需要同样小心线程2做的其他事情,以确保线程3可见.如果线程2需要设置其他状态,那么命令也很重要.
在简单的情况下,是的,你很好,但如果它变得比仅仅简单地轻弹标志更复杂,那么这就变得更难以推理.
Tom*_*ine 18
基本上所有AtomicBoolean都是一个volatile boolean对象.
每个对象的开销很小.可能无关紧要,但可能有更多内存进入缓存.
如果你需要使用AtomicBooleanFieldUpdater那么就会有相当多的性能开销.如果你不打算经常这样做(如attach在NIO中).