【问题标题】:AtomicBoolean vs volatile [duplicate]AtomicBoolean vs volatile [重复]
【发布时间】:2014-06-26 00:49:05
【问题描述】:

在我读过的一本关于编程的书中:

对于“无限”循环,应该有一些方法告诉线程 不再需要它,例如通过 AtomicBoolean 标志

如果不是AtomicBoolean 而是volatile boolean 怎么办?对于上述情况,使用 AtomicBoolean 而不是 volatile boolean 可以消除哪些负面影响?

如果我们将变量专门用作线程终止的标志,那么AtomicBooleanvolatileboolean之间还有区别吗?

【问题讨论】:

标签: java boolean atomic volatile


【解决方案1】:

我认为 compare-and-set 和 getAndSet 操作对于 volatile 变量不是原子的。还要检查 teto here 给出的描述

【讨论】:

  • 确实,当用作应该停止不同线程上的循环的标志时,我看不到原子比较和设置操作的要求,如果情况是应该停止 ThreadB 的 ThreadA .
【解决方案2】:

使用AtomicBoolean 所有读写操作都是原子的(顾名思义)。使用volatile boolean,当两个线程同时访问变量时,您仍然必须处理竞争条件。

【讨论】:

  • 如果我只使用那个标志来设置/确定线程终止条件,还有区别吗?
  • 如果一次只有一个线程正在写入,并且可以稍后完成一个交互,那么使用volatile boolean 将没有问题。
【解决方案3】:

这取决于你的循环的具体实现细节外部事件设置所说的停止标志。实际上,如果您可以确保只有 一个 线程更新 volatile,则 volatile 就足够了。示例:

volatile boolean alive = true;

void loop() {
     while (alive) {
     }
}

void stop() {
    alive = 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。

【讨论】:

    猜你喜欢
    • 2015-12-28
    • 2017-08-29
    • 2020-10-11
    • 1970-01-01
    • 2013-06-13
    • 2012-05-08
    • 2011-06-20
    • 2015-03-25
    相关资源
    最近更新 更多