此并发遗留代码是否需要易变

时间:2017-02-10 16:27:48

标签: java multithreading concurrency

我正在努力处理一些并发遗留代码,并想知道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?等一般问题/答案归结为此特定问题。

1 个答案:

答案 0 :(得分:0)

根据最受欢迎的评论:

  • Mick Mnemonic
      

    isRunning()不是synchronized,因此mode应为volatile

  • Brian Goetz
      

    您在mode上有数据竞赛。它是从同步块外部访问的。首选应该是同步isRunninggetMode;制作模式volatile是一种更高级的游戏。 (先走,然后飞。)