与易失性“状态标志”布尔值同步吗?

时间:2019-07-10 08:47:16

标签: java multithreading atomicboolean

我已经了解了volatile用法的“状态标志”模式。 它说如果状态标志不依赖于任何其他状态,则可以不带任何同步地使用volatile。它将保证其他线程的标志可见性。而且,写入布尔值是原子的。

但是在与other相关的问题中,据说只有一个线程可以修改该标志时,使用volotile是安全的。否则,我需要使用任何同步或AtomicBoolean

在我的示例中,我具有stopped标志,但是可以在一个线程内进行更多修改:方法stop()continue()doSmth()不会更新任何状态。如果假设在stop()方法之后立即调用continue()时不执行任何工作,那代码是线程安全的吗?

class MyClass {
    private volatile boolean stopped;

    public void doWork() {
        while(!sopeed) {
            doSmth();
        }
    }

    public void stop() {
        stopped = true;
    }

    public void continue() {
        stopped = false;
    }
}

对我来说,应该。请问我是否弄错了?

1 个答案:

答案 0 :(得分:0)

volatile仅确保对变量的更改可用于所有线程。

背景:线程可能会创建共享变量的本地副本。 volatile的作用是将这些局部变量的值与全局共享变量同步。

但是,在单个条目,监视/关键区域的情况下,这不能同步

java.util.concurrent的整个工具世界提供了诸如确保只有一个线程可以更改值之类的功能。如果您想从头开始,可以用两个变量做一些阻止事情:搜索 Dijkstra算法

在这里,我认为AtomicBoolean对于非阻塞用法可能很好。


如果您想获得暂停分别的全局布尔状态。切换时(您的stopped恢复线程,而不是一些难看的忙碌等待

public void run () {
    while (true) {
        doWork(); 
        try {
            barrier.await();
        } catch (InterruptedException | BrokenBarrierException ex) {
            return;
        }
    }
}

使用全局CyclicBarrier-不是最好的API,因为它可以与N个预定义的Runnable一起使用。