JAVA Synchronized 與 Lock接口的區別

  • 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() {
             
        }
    }
相關文章
相關標籤/搜索