2012-07-20 40 views
2

稱爲可重入鎖和外來方法從有效的Java第10章併發從同步區(有效的Java項目)

假設 你是從一個同步的區域,而中調用一個陌生的方法不受同步區域保護的 暫時無效。由於 鎖在Java編程語言是可重入,這樣的調用不會死鎖

現在來看看下面的代碼:

// Broken - invokes alien method from synchronized block! 
public class ObservableSet<E> extends ForwardingSet<E> { 
    public ObservableSet(Set<E> set) { 
    super(set); 
    } 

    private final List<SetObserver<E>> observers = new ArrayList<SetObserver<E>>(); 

    private void notifyElementAdded(E element) { 
    synchronized (observers) { 
     for (SetObserver<E> observer : observers) 
     observer.alienMethod(this, element); 
    } 
    } 
} 

所以考慮SetObserversObservableSet是兩個獨立編寫的類和他們居住在不同的包裝中,alienMethod()SetObserverObservableSet類別不同。現在說當​​被調用時觀察者不是一致的狀態。那麼可重入鎖的問題在哪裏呢?如果外來方法也在同一個鎖上同步,即「觀察者」,那麼重入只會成爲問題,但在這裏似乎不是這種情況,或者我在這裏錯過了什麼?

回答

6

如果​​導致事件被觸發,結果重新輸入相同的notifyElementAdded方法會發生什麼?這是一個現實世界的危險,我曾經被它咬過一次。

在這個特殊的情況下,你必須作出你的清單的安全副本,並在平靜中運行。

+0

但這是你在這裏做出的一個特殊假設。根據你的假設,是的副本應該可以解決問題,但在引用中沒有明確提及。所以讓我們假設我們不知道外星人的方法會做什麼。 – Geek 2012-07-20 12:46:14

+1

沒有特別的假設,指出可以用外來碼重新輸入相同的方法。需要跳過的箍筋的確切數量是次要的。 – 2012-07-20 12:48:51