2013-01-13 94 views
0

當java線程彼此通信但不需要顯式同步(因此不需要調用同步對象來同步執行)時,最佳實踐是什麼確保相關線程的正確可見性?Java線程可見性 - 沒有顯式同步的最佳可見性實踐

例如:

class B extends Thread { 
    ... 
    A instanceOfA = ...; 

    B(){ 
      instanceOfA.registerHandler(new Handler(){ 
       @Override 
       handle(SomeObjectToBeVisibile o){ 
        ... 
       } 
      }); 
    } 
} 

class A extends Thread { 
    ... 
    void registerSomeHandlerMethod(HandlerMethod handler){...} 

    void executeHandlers(){ 
      for(each registered handler){ 
       handler.handle(instanceOfSomeObjectToBeVisible); 
      } 

    } 
} 

如果我沒有記錯的話,有一個潛在的可見性問題的處理程序「處理」方法調用傳遞一些構造對象,那麼可能不會顯示在接收有道線程(陳舊的值,例如),對嗎?如果是,如何強制查看而不使用同步?

謝謝。

+0

不要顯式擴展Thread。在圍繞它們開始線程之前,始終創建對象,並且在構建時不會出現多線程問題。 –

回答

0

不要害怕同步,如果同步塊很小且很快,在你的情況下是這樣,鎖定解鎖不會引起任何問題。

您可以使用「無鎖」併發數據結構,如ConcurrentLinkedQueue。 (這對你的情況來說不會很快)

編輯:它看起來像你擔心傳遞給handle()的參數的可見性,而不是處理程序本身。

+0

是的,這是關於參數。 – xSNRG

4

應該可以使用volatile修飾符,不過我建議你使用AtomicReference

此外,如果你傳遞一個對象,這是不可改變的 - 然後就會出現一點問題都沒有,因爲最後的字段保證在構造函數結束執行前被初始化。

+0

你的意思是讓內部字段「最終」?不,情況並非如此。感謝使用AtomicReference的提示。 – xSNRG

+0

AtomicReference只是一個volatile變量的包裝。如果唯一的擔心是能見度,那麼揮發性就足夠了(稍微簡單一些)。 – assylias

+0

@assylias你錯了,它不僅僅是一個「包裝」,它提供了CAS支持。 – jdevelop