2017-01-14 26 views
2

如果我有一個來自同步塊的返回語句,我對釋放鎖的點感到困惑;發現我已經添加了try-finally塊並在最終阻止打印中添加了一個sysout'lock released',但是我可以清楚地看到,即使在'release'語句被打印之前,第二個線程已經獲得了鎖定。鎖何時釋放?什麼是保證事情不會變得混亂?如果我從同步塊返回,鎖何時釋放?

public static int testClassLevelMonitor() throws InterruptedException { 
    try { 
    synchronized(TestLocks.class) { 
     System.out.println("Static Block : Thread " + Thread.currentThread().getName() + " -- have the lock"); 
     Thread.currentThread().sleep(1000); 
     return 0; 
    } 
    } finally { 
     System.out.println("Static Block : Thread " + Thread.currentThread().getName() + " -- released the lock"); 
     System.out.println("\n\n"); 
    } 
} 

靜態塊:線程池1線程1 - 有鎖

靜態塊:線程池1線程2 - 有鎖

靜塊:線程池1線程1 - 釋放鎖

靜態塊:線程池1線程2 - 釋放鎖

+2

一旦它保護的區塊完成,就可以釋放鎖定,這意味着在返回之後但在最終區塊之前。這並不意味着如果jvm認爲它會提高性能,則不允許jvm保持更長的鎖定時間。 – Voo

+1

當一個線程到達'finally'塊時,它釋放了鎖。這時你不會考慮事件的順序。下一個線程可能會獲取該鎖並首先從同步塊打印其輸出;或者第一個線程可能首先從「finally」塊打印它的消息。您無法提前知道訂單。 –

+0

你還沒有發佈'TestLocks.java'以及你如何創建'thread-1'和'thread-2'?我最強烈的懷疑是'testClassLevelMonitor()'synchronized方法獲取了正在運行該方法的對象的鎖定,但有兩個不同的線程對象調用它。 – fabfas

回答

2

​​聲明在Java Language Specification中指定。

SynchronizedStatement: 
    synchronized (Expression) Block 
  • [..]
  • 否則,讓Expression的非空值是V。正在執行的線程鎖定與V關聯的監視器。然後Block 被執行,然後有一個選擇:
    • 如果Block的執行正常完成,然後將顯示器解鎖和​​語句正常完成。
    • 如果Block的執行出於任何原因突然完成,然後將顯示器解鎖並且​​語句completes abruptlyreturn突然完成)出於同樣的原因。

換句話說,鎖只舉辦了​​語句體的長度。

System.out.println("Static Block : Thread " + Thread.currentThread().getName() + " -- have the lock"); 
Thread.currentThread().sleep(1000); 
return 0; 

finally塊將在沒有保持鎖的情況下執行。


在佔用鎖時,執行的線程將推動評估return語句到堆棧的結果,釋放鎖,執行finally塊,然後返回該值。