2
我与一些并发的遗留代码挣扎,不知是否stopLatch
和/或mode
应该是volatile
:这是否并发遗留代码需要挥发性
public class MyClass {
private final ExecutorService executor = Executors.newSingleThreadExecutor();
private MyModeEnum mode = MyModeEnum.NONE;
private CountDownLatch stopLatch;
public synchronized void start(final MyModeEnum mode) {
assert mode != null && mode != MyModeEnum.NONE;
if (isRunning()) {
// Throw an exception.
}
this.mode = mode;
stopLatch = new CountDownLatch(1);
executor.execute(() -> {
try {
// Pre and post operations not under control around stopLatch.await().
} catch (final Exception e) {
stop();
// Further exception handling.
} finally {
MyClass.this.mode = MyModeEnum.NONE;
}
});
}
public synchronized void stop() {
if (!isRunning()) {
return;
}
stopLatch.countDown();
}
public boolean isRunning() {
return mode != MyModeEnum.NONE;
}
public MyModeEnum getMode() {
return mode;
}
}
精心的解释非常赞赏。
编辑:我不能归结为一般问题/答案,如When exactly do you use the volatile keyword in Java?对这个特定的问题。
同步块有当他们进入和退出所有线程同步,所以我不认为'volatile'是必要的。 – khelwood
我会说只有'mode'需要'volatile',因为任何变化都需要对其他线程可见。注意:'assert'好像和'isRunning()'做的是一样的工作,我错了吗? – sp00m
'isRunning() ''不'同步',所以'mode'应该是'volatile' ' –