我正在瀏覽「JAX London 2011」presentation on "Modern Java Concurrency"。在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開發人員。我不認爲他們都會錯過這個! 那麼,我錯過了什麼?
PS: - 我可以理解,一個變量應聲明volatile
如果它是(可能)由多個線程共享,如在雙重檢查鎖定模式:
class Foo {
private volatile Helper helper = null;
public Helper getHelper() {
if (helper == null) {
synchronized(this) {
if (helper == null)
helper = new Helper();
}
}
return helper;
}
}
任何人都想解釋-1? – Gray 2013-03-26 22:42:41
謝謝。我認爲可以安全地假設'shutdown'只能從QueueReaderTask實例中修改,因爲:a。 'shutdown'變量被聲明爲private。灣該類沒有「...」(意思是沒有解釋或遺漏的代碼)。 C。沒有setShutdown()。 d。變量的含義似乎是:「如果我無法正確完成對隊列中的對象的處理,就會自行關閉」。如果該線程無法正確處理隊列中的對象,則另一個線程不應該關閉。 – brainOverflow 2013-03-26 22:43:55
我同意@VenkateshDhandapani。 – Gray 2013-03-26 22:44:35