1. 程式人生 > 其它 >JAVA Synchronized 與 Lock介面的區別

JAVA Synchronized 與 Lock介面的區別

2019獨角獸企業重金招聘Python工程師標準>>> hot3.png

  • synchronized

  1. 關於synchronized欄位,不管該關鍵字是修飾方法還是修飾同步程式碼塊,synchronzed拿到的都是物件。
  2. 當synchronized修飾的是方法時,synchronized所拿到的是呼叫該方法的物件的鎖,一般情況下都是this的鎖;
  3. 當synchronized修飾的靜態方法時,由於靜態方法不包含this,屬於類層次的方法,所以,synchronized拿到的是這個方法所屬Class物件的鎖。
  4. synchronized鎖屬於JAVA語言特性,JVM會自動釋放不需要使用者操作,因此不會導致死鎖現象發生。
  • synchronized鎖釋放時一般是以下三種情況:
  1. 佔有鎖的執行緒執行完了程式碼塊,然後釋放對鎖的佔有;
  2. 佔有鎖的執行緒發生了異常,此時JVM會讓執行緒自動釋放鎖;
  3. 佔有鎖的執行緒呼叫了wait()方法,從而進入了WAITING狀態需要釋放鎖。
  • lock介面

  1. 而Lock介面需要使用者手動釋放,在發生異常時,如果沒有主動通過unLock()去釋放鎖,則很可能造成死鎖現象,因此使用Lock時需要在finally塊中釋放鎖;如:finally {lock.unlock(); }
  2. Lock可以讓等待鎖的執行緒響應中斷,而synchronized卻不行,使用synchronized時,等待的執行緒會一直等待下去,不能夠響應中斷;
  3. 通過Lock可以知道有沒有成功獲取鎖,而synchronized卻無法辦到。如lock.tryLock()
  4. Lock可以提高多個執行緒進行讀操作的效率,如ReentrantReadWriteLock
  5. 在效能上來說,如果競爭資源不激烈,兩者的效能是差不多的,而當競爭資源非常激烈時(即有大量執行緒同時競爭),此時Lock的效能要遠遠優於synchronized。所以說,在具體使用時要根據適當情況選擇。
  • 鎖的相關概念介紹

  1. 可重入鎖,synchronized和ReentrantLock都是可重入鎖,當一個執行緒執行到某個synchronized方法時,比如說method1,而在method1中會呼叫另外一個synchronized方法method2,此時執行緒不必重新去申請鎖,而是可以直接執行方法method2。因為如之前所說syncchronized所拿到的是呼叫該方法的物件的鎖是this鎖,即MyClass類的物件,所以呼叫method2不需要重新獲得鎖。假如synchronized不具備可重入性,此時執行緒A需要重新申請鎖。但是這就會造成一個問題,因為執行緒A已經持有了該物件的鎖,而又在申請獲取該物件的鎖,這樣就會執行緒A一直等待永遠不會獲取到的鎖。
    class MyClass {
        public synchronized void method1() {
            method2();
        }
         
        public synchronized void method2() {
             
        }
    }

轉載於:https://my.oschina.net/kdy1994/blog/1925126