(十一)java中synchronized和ReentrantLock有什么不同?ReentrantLock優(yōu)勢(shì)是什么?synchronized性能差,為什么?(1)

------------------------------版本一---------------------------------

1.區(qū)別:

1)Lock是一個(gè)接口,而synchronized是Java中的關(guān)鍵字,synchronized是內(nèi)置的語言實(shí)現(xiàn);

2)synchronized在發(fā)生異常時(shí),會(huì)自動(dòng)釋放線程占有的鎖,因此不會(huì)導(dǎo)致死鎖現(xiàn)象發(fā)生;而Lock在發(fā)生異常時(shí),如果沒有主動(dòng)通過unLock()去釋放鎖,則很可能造成死鎖現(xiàn)象,因此使用Lock時(shí)需要在finally塊中釋放鎖;

3)Lock可以讓等待鎖的線程響應(yīng)中斷,而synchronized卻不行,使用synchronized時(shí),等待的線程會(huì)一直等待下去,不能夠響應(yīng)中斷;

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

5)Lock可以提高多個(gè)線程進(jìn)行操作的效率。

總結(jié):ReentrantLock相比synchronized,增加了一些高級(jí)的功能。但也有一定缺陷。

在ReentrantLock類中定義了很多方法,比如:

isFair()//判斷鎖是否是公平鎖

isLocked()//判斷鎖是否被任何線程獲取了

isHeldByCurrentThread()//判斷鎖是否被當(dāng)前線程獲取了

hasQueuedThreads()//判斷是否有線程在等待該鎖

2.兩者在鎖的相關(guān)概念上區(qū)別:

1)可中斷鎖

顧名思義,就是可以相應(yīng)中斷的鎖。

在Java中,synchronized就不是可中斷鎖,而Lock是可中斷鎖。如果某一線程A正在執(zhí)行鎖中的代碼,另一線程B正在等待獲取該鎖,可能由于等待時(shí)間過長(zhǎng),線程B不想等待了,想先處理其他事情,我們可以讓它中斷自己或者在別的線程中中斷它,這種就是可中斷鎖。

lockInterruptibly()的用法體現(xiàn)了Lock的可中斷性。

2)公平鎖

公平鎖即盡量以請(qǐng)求鎖的順序來獲取鎖。比如同是有多個(gè)線程在等待一個(gè)鎖,當(dāng)這個(gè)鎖被釋放時(shí),等待時(shí)間最久的線程(最先請(qǐng)求的線程)會(huì)獲得該鎖(并不是絕對(duì)的,大體上是這種順序),這種就是公平鎖。

非公平鎖即無法保證鎖的獲取是按照請(qǐng)求鎖的順序進(jìn)行的。這樣就可能導(dǎo)致某個(gè)或者一些線程永遠(yuǎn)獲取不到鎖

在Java中,synchronized就是公平鎖,它無法保證等待的線程獲取鎖的順序。ReentrantLock可以設(shè)置成公平鎖

3)讀寫鎖

讀寫鎖將對(duì)一個(gè)資源(比如文件)的訪問分成了2個(gè)鎖,一個(gè)讀鎖和一個(gè)寫鎖

正因?yàn)橛辛俗x寫鎖,才使得多個(gè)線程之間的讀操作可以并發(fā)進(jìn)行,不需要同步,而操作需要同步進(jìn)行提高效率。

ReadWriteLock就是讀寫鎖,它是一個(gè)接口,ReentrantReadWriteLock實(shí)現(xiàn)了這個(gè)接口。

可以通過readLock()獲取讀鎖,通過writeLock()獲取寫鎖。

4)綁定多個(gè)條件

一個(gè)ReentrantLock對(duì)象可以同時(shí)綁定多個(gè)Condition對(duì)象,而在synchronized中,鎖對(duì)象的wait()和notify()或notifyAll()方法可以實(shí)現(xiàn)一個(gè)隱含的條件,如果要和多余一個(gè)條件關(guān)聯(lián)的時(shí)候,就不得不額外地添加一個(gè)鎖,而ReentrantLock則無須這么做,只需要多次調(diào)用new Condition()方法即可。

3.性能比較

在性能上來說,如果競(jìng)爭(zhēng)資源不激烈,兩者的性能是差不多的,而當(dāng)競(jìng)爭(zhēng)資源非常激烈時(shí)(即有大量線程同時(shí)競(jìng)爭(zhēng)),此時(shí)ReentrantLock的性能要遠(yuǎn)遠(yuǎn)優(yōu)于synchronized。所以說,在具體使用時(shí)要根據(jù)適當(dāng)情況選擇。

在JDK1.5中,synchronized是性能低效的。因?yàn)檫@是一個(gè)重量級(jí)操作,它對(duì)性能最大的影響是阻塞的是實(shí)現(xiàn),掛起線程和恢復(fù)線程的操作都需要轉(zhuǎn)入內(nèi)核態(tài)中完成,這些操作給系統(tǒng)的并發(fā)性帶來了很大的壓力。相比之下使用Java提供的ReentrankLock對(duì)象,性能更高一些。到了JDK1.6,發(fā)生了變化,對(duì)synchronize加入了很多優(yōu)化措施,有自適應(yīng)自旋,鎖消除,鎖粗化,輕量級(jí)鎖,偏向鎖等等。導(dǎo)致在JDK1.6上synchronize的性能并不比Lock差。官方也表示,他們也更支持synchronize,在未來的版本中還有優(yōu)化余地,所以還是提倡在synchronized能實(shí)現(xiàn)需求的情況下,優(yōu)先考慮使用synchronized來進(jìn)行同步

http://www.itdecent.cn/p/96c89e6e7e90

------------------------------版本二---------------------------------

一、兩者的共同點(diǎn):

1)協(xié)調(diào)多線程對(duì)共享對(duì)象、變量的訪問

2)可重入,同一線程可以多次獲得同一個(gè)鎖

3)都保證了可見性和互斥性

兩者的不同點(diǎn):

1)ReentrantLock顯示獲得、釋放鎖,synchronized隱式獲得釋放鎖

2)ReentrantLock可響應(yīng)中斷(通過lock.lockInterruptibly()來實(shí)現(xiàn)這個(gè)機(jī)制)、可輪回,synchronized是不可以響應(yīng)中斷的,為處理鎖不可用性提供了更靈活性

3)ReentrantLock是API級(jí)別的,synchronized是JVM級(jí)別的

4)ReentrantLock可以實(shí)現(xiàn)公平鎖

5)ReentrantLock通過Condition可以綁定多個(gè)條件,用來實(shí)現(xiàn)分組喚醒需要喚醒的線程們,而不是像synchronized要么隨機(jī)喚醒一個(gè)線程要么喚醒全部線程。

6)底層實(shí)現(xiàn)不一樣, synchronized是同步阻塞,使用的是悲觀并發(fā)策略,lock是同步非阻塞,采用的是樂觀并發(fā)策略

三、雖然ReentrantLock可以提供比synchronized更高級(jí)的功能,但是仍不能替換synchronized

《java并發(fā)編程實(shí)戰(zhàn)》上說是因?yàn)槿绻褂胷eentrantlock時(shí),你沒有釋放鎖很難追蹤到最初發(fā)生錯(cuò)誤的位置,因?yàn)闆]有記錄應(yīng)該釋放鎖的位置和時(shí)間。網(wǎng)上找了一下,沒有找到其他比較合理的答案,先暫且記住吧

幾個(gè)方法:

1) boolean tryLock(long time, TimeUnit unit) throws InterruptedException;

time:等待鎖定的最長(zhǎng)時(shí)間

unit: 時(shí)間單位

這個(gè)方法起到了定時(shí)鎖的作用,如果在指定時(shí)間內(nèi)沒有獲取到鎖,將會(huì)返回false

應(yīng)用:具有時(shí)間限制的操作時(shí)使用

四、什么時(shí)候選擇使用synchronized,什么使用選擇使用ReentrantLock

僅當(dāng)synchronized不能滿足時(shí)才使用ReentrantLockk,因?yàn)槭褂?b>ReentrantLock要非常小心,不釋放鎖將影響其他需要該鎖的代碼塊運(yùn)行

不能使用synchronized不滿足的情形:

1)公平性

2)可中斷

4)分塊結(jié)構(gòu)的加鎖,比如jdk1.7ConcurrentHashMap的分段鎖(目前還不是提別理解這個(gè),先記住這個(gè)例子,后頭補(bǔ)充)

五、synchronized和ReentrantLock兩者之間性能的比較

從jdk1.5以后,性能就差不多了,因?yàn)閖vm對(duì)synchronized進(jìn)行了很多優(yōu)化

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容