jdk1.8对synchronized锁的优化
synchronized 鎖的優(yōu)化:鎖的四種狀態(tài)-無鎖,偏向鎖、輕量級鎖,重量級鎖
1、偏向鎖:原因是大多數(shù)時(shí)候是不存在鎖競爭的,常常是一個(gè)線程多次獲得同一個(gè)鎖,因此如果每次都要競爭鎖會增大很多沒有必要付出的代價(jià),為了降低獲取鎖的代價(jià),才引入的偏向鎖
偏向鎖的升級:當(dāng)線程1訪問代碼塊并獲取鎖對象時(shí),會在java對象頭和棧幀中記錄偏向的鎖的threadID,因?yàn)?strong>偏向鎖不會主動(dòng)釋放鎖,以后線程1再次獲取鎖時(shí)比較當(dāng)前線程的threadID和Java對象頭中的threadID是否一致,如果一致(還是線程1獲取鎖對象),則無需使用CAS來加鎖、解鎖;如果不一致(如線程2要競爭鎖對象,而偏向鎖不會主動(dòng)釋放因此還是存儲的線程1的threadID),那么查看Java對象頭中記錄線程1是否存活,如果沒有存活,那么鎖對象被重置為無鎖狀態(tài),其它線程(線程2)可以競爭將其設(shè)置為偏向鎖;如果存活,那么立刻查找該線程(線程1)的棧幀信息,如果還是需要繼續(xù)持有這個(gè)鎖對象,那么暫停當(dāng)前線程1,撤銷偏向鎖,升級為輕量級鎖,如果線程1 不再使用該鎖對象,那么將鎖對象狀態(tài)設(shè)為無鎖狀態(tài),重新偏向新的線程。
?
2、輕量級鎖:考慮的是競爭鎖對象的線程不多,而且線程持有鎖的時(shí)間也不長的情景。因?yàn)樽枞€程需要CPU從用戶態(tài)轉(zhuǎn)到內(nèi)核態(tài),代價(jià)較大,如果剛剛阻塞不久這個(gè)鎖就被釋放了,那這個(gè)代價(jià)就有點(diǎn)得不償失了,因此這個(gè)時(shí)候就干脆不阻塞這個(gè)線程,讓它自旋這等待鎖釋放。
輕量級鎖什么時(shí)候升級為重量級鎖?線程1獲取輕量級鎖時(shí)會先把鎖對象的對象頭MarkWord復(fù)制一份到線程1的棧幀中創(chuàng)建的用于存儲鎖記錄的空間(稱為DisplacedMarkWord),然后使用CAS把對象頭中的內(nèi)容替換為線程1存儲的鎖記錄(DisplacedMarkWord)的地址;
如果在線程1復(fù)制對象頭的同時(shí)(在線程1CAS之前),線程2也準(zhǔn)備獲取鎖,復(fù)制了對象頭到線程2的鎖記錄空間中,但是在線程2CAS的時(shí)候,發(fā)現(xiàn)線程1已經(jīng)把對象頭換了,線程2的CAS失敗,那么線程2就嘗試使用自旋鎖來等待線程1釋放鎖。
但是如果自旋的時(shí)間太長也不行,因?yàn)樽孕且腃PU的,因此自旋的次數(shù)是有限制的,比如10次或者100次,如果自旋次數(shù)到了線程1還沒有釋放鎖,或者線程1還在執(zhí)行,線程2還在自旋等待,這時(shí)又有一個(gè)線程3過來競爭這個(gè)鎖對象,那么這個(gè)時(shí)候輕量級鎖就會膨脹為重量級鎖。重量級鎖把除了擁有鎖的線程都阻塞,防止CPU空轉(zhuǎn)。
3、重量級鎖:為了避免無用的自旋,輕量級鎖一旦膨脹為重量級鎖就不會再降級為輕量級鎖了;偏向鎖升級為輕量級鎖也不能再降級為偏向鎖。一句話就是鎖可以升級不可以降級,但是偏向鎖狀態(tài)可以被重置為無鎖狀態(tài)。
4、鎖粗化:同步塊的作用范圍應(yīng)該盡可能小,僅在共享數(shù)據(jù)的實(shí)際作用域中才進(jìn)行同步,這樣做的目的是為了使需要同步的操作數(shù)量盡可能縮小,縮短阻塞時(shí)間,如果存在鎖競爭,那么等待鎖的線程也能盡快拿到鎖。 但是加鎖解鎖也需要消耗資源,如果存在一系列的連續(xù)加鎖解鎖操作,可能會導(dǎo)致不必要的性能損耗。 鎖粗化就是將多個(gè)連續(xù)的加鎖、解鎖操作連接在一起,擴(kuò)展成一個(gè)范圍更大的鎖,避免頻繁的加鎖解鎖操作。
5、鎖消除
Java虛擬機(jī)在JIT編譯時(shí)(可以簡單理解為當(dāng)某段代碼即將第一次被執(zhí)行時(shí)進(jìn)行編譯,又稱即時(shí)編譯),通過對運(yùn)行上下文的掃描,經(jīng)過逃逸分析,去除不可能存在共享資源競爭的鎖,通過這種方式消除沒有必要的鎖,可以節(jié)省毫無意義的請求鎖時(shí)間
總結(jié):輕量級鎖,重量級鎖是針對不同的場景的,偏向鎖是針對不存在或很少存在資源競爭的情況,輕量級鎖是存在線程競爭,執(zhí)行周期比較短的情況,大部分都是這情況,最主要的原因是輕量級鎖是為了避免重量級鎖,產(chǎn)生操作系統(tǒng)層面的用戶態(tài)和內(nèi)核態(tài)切換帶來的開銷。輕量級鎖自旋遠(yuǎn)比用戶態(tài)/內(nèi)核態(tài)系統(tǒng)調(diào)度帶來的自旋消耗要小的多,但是自旋是有CPU消耗的,所以又不可以永久的進(jìn)行自旋,因此升級為重量級鎖,進(jìn)行線程同步處理。
總結(jié)
以上是生活随笔為你收集整理的jdk1.8对synchronized锁的优化的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: w ndows10隐藏桌面设置,Win1
- 下一篇: PDPS教程之工艺仿真必备软件