「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開発者がいたと思います。私は彼ら全員がこれを見逃したとは思わない!だから、私は何が欠けていますか?
volatile
PS: -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;
}
}