「ModernJavaConcurrency」に関する「JAXLondon2011」のプレゼンテーションを行っていました。43:20〜43:40の間に、聴衆の人が、shutdown以下のコードの変数はとして宣言されるべきでvolatileあり、プレゼンターはそれに同意すると言います(そして、それは以前にも指摘されたと言いますが、彼らはただプレゼンテーションを変更できませんでした)。問題のコードは次のとおりです。
public abstract class QueueReaderTask implements Runnable {
  private boolean shutdown = false;
  protected BlockingQueue<WorkUnit<String>> lbq;
  public void run() {
    while (!shutdown) {
      try {
        WorkUnit<String> wu = lbq.poll(10, TimeUnit.MILLISECONDS);
        if (wu != null) { doAction(wu.getWork()); }
      } catch (InterruptedException e) {
        shutdown = true;
      }
    }
  }
  public abstract void doAction(String msg);
  public void setQueue(BlockingQueue<WorkUnit<String>> q) { lbq = q; }
}
私の質問:私はそれshutdownが宣言されるべきだとは思いませんvolatile。私の推論はshutdown、のメンバーであるためRunnable、各タスク/スレッドはその変数の個別のプライベートコピーを持っているということです。それで、なぜそれを作るのvolatileですか?
しかし、これはJAX 2011で議論されたので、その聴衆には多くのエキスパートJava開発者がいたと思います。私は彼ら全員がこれを見逃したとは思わない!だから、私は何が欠けていますか?
volatilePS: -Double-Checked-Lockingパターンのように、変数が(潜在的に)複数のスレッドによって共有されている場合は、変数を宣言する必要があることを理解できます。
class Foo {
        private volatile Helper helper = null;
        public Helper getHelper() {
            if (helper == null) {
                synchronized(this) {
                    if (helper == null)
                        helper = new Helper();
                }
            }
            return helper;
        }
}