0

我已经阅读了有关使用的“状态标志”模式volatile。它说volatile如果状态标志不依赖于任何其他状态,我可以在没有任何同步的情况下使用。它将保证标志对其他线程的可见性。此外,写入布尔值是原子的。

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

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

class MyClass {
    private volatile boolean stopped;

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

    public void stop() {
        stopped = true;
    }

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

至于我,应该。如果我错了,你能澄清一下吗?

4

1 回答 1

2

volatile只需确保对变量的更改对所有线程都可用。

背景:线程可以制作共享变量的本地副本。将这些局部变量的值与全局共享变量同步是什么volatile效果。

但是,这不会在单个条目、监视器/关键区域的 java 中同步。

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

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


如果您想实现具有暂停相应的全局布尔状态。切换时恢复线程(你的stopped),而不是一些丑陋的忙等待

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

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

于 2019-07-10T09:45:54.843 回答