2013-03-26 61 views
3

我正在瀏覽「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。 我的推理是shutdownRunnable的成員,每個任務/線程將擁有該變量的不同私有副本。那麼,爲什麼要它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; 
     } 
} 

回答

5

每個任務/線程將具有該變量的不同私有副本。那麼,爲什麼讓它變得「不穩定」呢?

你是正確的,如果布爾shutdown僅從QueueReaderTask實例中修改。在這種情況下,shutdown僅由一個線程修改,不需要爲volatile

坦率地說,代碼看起來很奇怪。爲什麼趕上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; 
    } 
} 

也許有額外的代碼被刪除的帖子?如果不是,我想知道這是否是從方法調用中的shutdown設置爲true 的大部分代碼複製並粘貼的。

P.S: - 我可以理解,一個變量應被聲明爲「易失性」,如果它是(可能)由多個線程共享,如在雙重檢查鎖定模式:

右。一個典型的模式是shutdown從另一個線程中修改,該線程告訴線程停止處理。在這種情況下,它需要是volatile

+0

任何人都想解釋-1? – Gray 2013-03-26 22:42:41

+1

謝謝。我認爲可以安全地假設'shutdown'只能從QueueReaderTask實例中修改,因爲:a。 'shutdown'變量被聲明爲private。灣該類沒有「...」(意思是沒有解釋或遺漏的代碼)。 C。沒有setShutdown()。 d。變量的含義似乎是:「如果我無法正確完成對隊列中的對象的處理,就會自行關閉」。如果該線程無法正確處理隊列中的對象,則另一個線程不應該關閉。 – brainOverflow 2013-03-26 22:43:55

+0

我同意@VenkateshDhandapani。 – Gray 2013-03-26 22:44:35