在一本关于编程的书中,我读到了:
对于“无限”循环,应该有一些方法告诉线程 它不再需要,例如通过AtomicBoolean标志
如果AtomicBoolean
代替volatile boolean
而不是AtomicBoolean
怎么办?对于上述案例,volatile boolean
与AtomicBoolean
相比,消除了哪些负面影响?
如果我们将变量专门用作线程终止的标志,那么volatile
和boolean
{{1}}之间是否存在差异?
答案 0 :(得分:2)
这取决于你的循环的具体实现细节和外部事件设置表示停止标志。实际上,如果可以确保只有一个线程更新volatile, volatile 就足够了。例如:
volatile boolean alive = true;
void loop() {
while (alive) {
}
}
void stop() {
alive = false;
}
这很好,因为只有一个可能的状态从true转换为false。
一旦变得有点复杂(例如反映循环状态的AtomicInteger),您将需要compareAndSet()样式操作来正确实现变量的状态转换。
示例:
volatile int state = NOT_STARTED;
void loop() {
state = RUNNING;
while (state == RUNNING) {
}
state = TERMINATED;
}
void stop() {
state = ABORT;
}
如果在执行“state = RUNNING”之前调用了stop(),这可能错过一个停止信号,所以这里需要compareAndSet以避免意外地用RUNNING覆盖ABORT。
答案 1 :(得分:1)
我认为compare-and-set和getAndSet操作对于volatile变量不是原子的。另请查看teto here
提供的说明答案 2 :(得分:1)
使用AtomicBoolean
所有读写操作都是原子的(如名称所示)。使用volatile boolean
,当两个线程同时访问变量时,你仍然需要处理竞争条件。