3

「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;
        }
}
4

1 に答える 1

5

各タスク/スレッドには、その変数の個別のプライベートコピーがあります。それで、なぜそれを「揮発性」にするのですか?

ブール値がインスタンス内からのみ変更される場合は正しいです。その場合、1つのスレッドによってのみ変更され、である必要はありません。shutdownQueueReaderTaskshutdownvolatile

率直に言って、コードは私には奇妙に見えます。なぜキャッチInterruptedExceptionし、ブール値を設定してshutdownから、ループして終了します。なぜ今、次のことをするのですか?なぜshutdown旗を持っているのですか?

while (true) {
  try {
    WorkUnit<String> wu = lbq.poll(10, TimeUnit.MILLISECONDS);
    if (wu != null) { doAction(wu.getWork()); }
  } catch (InterruptedException e) {
     Thread.currentThread().interrupt();
     return;
  }
}

たぶん、投稿で削除された余分なコードがありますか?そうでない場合は、これが、メソッド呼び出しでshutdowntrueに設定されているコードのより大きなセクションからコピーして貼り付けられたのではないかと思います。

PS:-Double-Checked-Lockingパターンのように、変数が(潜在的に)複数のスレッドによって共有されている場合は、変数を「揮発性」と宣言する必要があることを理解できます。

右。典型的なパターンはshutdown、スレッドに処理を停止するように指示している別のスレッドから変更されたものです。その場合はである必要がありますvolatile

于 2013-03-26T22:36:03.120 に答える