我已经阅读了有关volatile
用法的"状态标志"模式。 它说如果状态标志不依赖于任何其他状态,我可以在没有任何同步的情况下使用该volatile
。它将保证标志对其他线程的可见性。此外,写入布尔值是原子的。
但在另一个相关问题中,据说当只有一个线程可以修改标志时,使用volotile
是安全的。否则,我需要使用任何同步或AtomicBoolean
。
在我的示例中,我有stopped
标志,但它可以从一个线程中多次修改:方法stop()
和continue()
.doSmth()
不会更新任何状态。如果假设在continue()
方法之后立即调用stop()
时可以不工作,那么代码线程安全吗?
class MyClass {
private volatile boolean stopped;
public void doWork() {
while(!stopped) {
doSmth();
}
}
public void stop() {
stopped = true;
}
public void continue() {
stopped = false;
}
}
至于我,应该。你能澄清一下我错了吗?
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
。