1. 程式人生 > 其它 >lock與synchroized的知識碎片

lock與synchroized的知識碎片

1、兩者都是可重入鎖

鎖可以重複獲取或者說是進化,則成為可重入鎖。

可重入性實際上表明瞭鎖的分配機制:基於執行緒的分配,而不是基於方法呼叫的分配。

2、synchronized就不是可中斷鎖,而Lock是可中斷鎖。

  如果某一執行緒A正在執行鎖中的程式碼,另一執行緒B正在等待獲取該鎖,可能由於等待時間過長,執行緒B不想等待了,想先處理其他事情,我們可以讓它中斷自己或者在別的執行緒中中斷它,這種就是可中斷鎖。

3、.公平鎖

  公平鎖即儘量以請求鎖的順序來獲取鎖。比如同是有多個執行緒在等待一個鎖,當這個鎖被釋放時,等待時間最久的執行緒(最先請求的執行緒)會獲得該所,這種就是 公平鎖。

  非公平鎖即無法保證鎖的獲取是按照請求鎖的順序進行的。這樣就可能導致某個或者一些執行緒永遠獲取不到鎖。

  在Java中,synchronized就是非公平鎖,它無法保證等待的執行緒獲取鎖的順序。

  而對於ReentrantLock和ReentrantReadWriteLock,它預設情況下是非公平鎖,但是可以設定為公平鎖。

在ReentrantLock中定義了2個靜態內部類,一個是NotFairSync,一個是FairSync,分別用來實現非公平鎖和公平鎖。

  我們可以在建立ReentrantLock物件時,通過以下方式來設定鎖的公平性:ReentrantLock lock =

newReentrantLock(true);

獲取鎖的執行緒釋放鎖只會有兩種情況:

  1)獲取鎖的執行緒執行完了該程式碼塊,然後執行緒釋放對鎖的佔有;

  2)執行緒執行發生異常,此時JVM會讓執行緒自動釋放鎖。

所以 lock提供一種機制可以不讓等待的執行緒一直無期限地等待下去(比如只等待一定的時間或者能夠響應中斷)。

總結幾點不同:

  1)Lock是一個介面,而synchronized是Java中的關鍵字,synchronized是內建的語言實現;

  2)synchronized在發生異常時,會自動釋放執行緒佔有的鎖,因此不會導致死鎖現象發生;而Lock在發生異常時,如果沒有主動通過unLock()去釋放鎖,則很可能造成死鎖現象,因此使用Lock時需要在finally塊中釋放鎖;

  3)Lock可以讓等待鎖的執行緒響應中斷,而synchronized卻不行,使用synchronized時,等待的執行緒會一直等待下去,不能夠響應中斷;

  4)通過Lock可以知道有沒有成功獲取鎖,而synchronized卻無法辦到。

  5)Lock可以提高多個執行緒進行讀操作的效率。

  在效能上來說,如果競爭資源不激烈,兩者的效能是差不多的,而當競爭資源非常激烈時(即有大量執行緒同時競爭),此時Lock的效能要遠遠優於synchronized。所以說,在具體使用時要根據適當情況選擇。

  publicinterfaceLock {

voidlock(); voidlockInterruptibly()throwsInterruptedException;///用來獲取鎖,等待獲取鎖的執行緒可以被打斷 booleantryLock();//用來獲取鎖。如果鎖已被其他執行緒獲取,則進行等待。必須手動釋放 booleantryLock(longtime, TimeUnit unit)throwsInterruptedException;// 嘗試獲取鎖,如果獲取成功,則返回true ,執行緒不會等待 voidunlock(); Condition newCondition();   }

注意點:

  當一個執行緒獲取了鎖之後,是不會被interrupt()方法中斷的。thread單獨呼叫interrupt()方法不能中斷正在執行過程中的執行緒,只能中斷阻塞過程中的執行緒。

  當通過lockInterruptibly()方法獲取某個鎖時,如果不能獲取到,只有進行等待的情況下,是可以響應中斷的。

  而用synchronized修飾的話,當一個執行緒處於等待某個鎖的狀態,是無法被中斷的,只有一直等待下去。

此文屬於摘錄,便於記憶