2012-02-10 28 views
2

問題:當顯示器已被鎖定時,重新進入同步塊的開銷是多少?重新進入同步塊的開銷

例如:

Object lock; 
void outer() 
{ 
    synchronized (lock) 
    { 
     innerOne(); 
     innerTwo(); 
    } 
} 

void innerOne() { synchronized (lock) { /* ... */ } } 
void innerTwo() { synchronized (lock) { /* ... */ } } 

的上述意圖是innerOneinnerTwo而線程上lock同步總是調用。

如果存在不可忽略的成本,是否有任何方法可以調用以放入assert聲明?我能找到的最接近的電話號碼是lock.notify(),以及IllegalMonitorStateException,例如

boolean isMonitorHeld(final Object object) 
{ 
    try { object.notify(); return true } 
    catch (final IllegalMonitorStateException e) { return false; } 
} 

哪想被使用:

void innerOne() { assert isMonitorHeld(lock); /* ... */ } 

有沒有對兩個選項的樣式任何意見或任何替代方案?

編輯

我希望更全面的答案不僅僅是「時間,看看」。我沒有能力預見我的代碼可能遇到的所有潛在情況,然後創建一個測試來展示這些情況。我想了解同步機制如何工作以瞭解它在不同情況下如何執行。我知道同步可能在不同的平臺上以不同的方式實現。在哪種情況下有所不同(主要在Solaris和Linux操作系統上)?

直覺上,我不認爲重新進入同步塊會有明顯的成本,因爲我發現的大多數文章都暗示無連鎖鎖是便宜的。但是,在這些方法中添加同步塊並不合適,因爲它給人的印象是它們可以被稱爲,而不是首先在鎖上同步。斷言提供了一個更好的想法,但它看起來像一個相當醜陋的黑客。我想知道是否有一個很好的理由,沒有一個更合理的選擇。

+1

你爲什麼不測量它?如果你*不能測量差異,那麼就沒有差別。 – skaffman 2012-02-10 09:47:53

回答

4

所以你的問題是要求一件事,然後你的問題的主體是要求別的。我可以肯定地說你的算法來測試一個線程是否持有鎖定會非常緩慢。比沒有檢查慢很多。拋出像這樣的例外是昂貴的。關於例外的規則之一。 請勿在程序中使用例外進行常規流量控制。異常控制流結構的一種形式,但您應該只將它們用於錯誤流量控制。主要是因爲每當你拋出一個異常時,它必須收集堆棧跟蹤以將其放入異常。這是一項昂貴的操作。您應該明確地使用異常,但僅限於它們的設計目的:錯誤流控制。

如果你想測試currentThread是否持有一個鎖,你應該使用Thread。holdsLock(對象監視器)

http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Thread.html#holdsLock(java.lang.Object

至於什麼是重新進入到用於currentThread一個同步塊中的成本已經是一個保持器。我沒有一個非常詳細的答案。我懷疑它調用holdLock的成本是多少。這可能是第一次檢查,如果它返回false,則請求將此線程添加到等待此對象監視器的線程列表中的代價更大。如果它是真的,它會跳到塊中。 Java線程,如果它想要高性能的話,這個問題的答案對於鎖的擁有者來說應該更快。對於不擁有鎖的線程來說,它肯定更昂貴。如果有什麼確切算法的答案,我可以在「Taming Threads」或Java規範中下注。

+0

謝謝,我完全錯過了Thread方法。重點是我有兩個或多個方法之間的共享邏輯。初始方法提供了同步,然後執行共享邏輯。從我的經驗來看,斷言對於描述(在代碼中)開發人員的意圖很有用。在我的情況下,實際上再次在監視器上同步給出了錯誤的印象,因爲它意味着可以在不首先獲得鎖的情況下調用該方法。如果沒有首先獲取鎖,該方法就不會被調用,所以如果這樣做的話,這是一個編程錯誤。 – SimonC 2012-02-13 08:30:01

+0

我重讀了你的問題,我想它更清楚一點。你只是想知道你是否可以在這兩種方法中使用assert語句,而不是像第一部分代碼那樣重新獲得鎖定。 – chubbsondubs 2012-02-13 14:28:21

+0

如果方法是公開的,我不會這麼做,但是對於使用assert的私有方法來說,會強制調用者鎖定,所以如果某人重構了代碼,那麼如果他們忘記了鎖,就會被捕獲。我敢打賭,我敢打賭,它與使用同步塊相同。 – chubbsondubs 2012-02-13 14:36:18

2

衡量它。在我的系統上可能沒有區別。在你的身上可能會有。您部署的系統可能仍然更加不同。