Java中synchronized關(guān)鍵字引出的多種鎖 問題

前言
Java 中的 synchronized關(guān)鍵字可以在多線程環(huán)境下用來作為線程安全的同步鎖。本文不討論 synchronized 的具體使用,而是研究下synchronized底層的鎖機(jī)制,以及這些鎖分別的優(yōu)缺點(diǎn)。
一 synchronized機(jī)制
synchronized關(guān)鍵字是JAVA中常用的同步功能,提供了簡單易用的鎖功能。
synchronized有三種用法,分別為:
用在普通方法上,能夠鎖住當(dāng)前對象。用在靜態(tài)方法上,能夠鎖住類用在代碼塊上,鎖住的是synchronized()里的對象
在JDK6之前,synchronized使用的是重量級鎖制,在之后synchronized加入了鎖膨脹機(jī)制,顯著提升了synchronized關(guān)鍵字的效率。
基于synchronized關(guān)鍵字,我們來了解下幾種類別的鎖,并且講解synchronized的鎖膨脹機(jī)制。
synchronized鎖是非公平鎖。并且一個被synchronized鎖住的對象或類,就是一把鎖。
另外一提,所有鎖都是存儲在Java對象頭里的,Java對象頭里的Mark Word里默認(rèn)存儲對象的HashCode,分代年齡和鎖標(biāo)記位。也就是說Mark Word記錄了鎖的狀態(tài)
二 鎖膨脹機(jī)制與幾類鎖
鎖膨脹是不可逆的
2.1 偏向鎖
synchronized在JDK1.6以后默認(rèn)開啟偏向鎖,synchronized最初都是偏向鎖
表現(xiàn):一個線程獲取鎖成功后,會在對象頭里記錄線程ID,以后該線程獲取和釋放鎖都沒有任何花費(fèi)。(因?yàn)樵撴i已經(jīng)被綁定在該線程上了,且在膨脹前不會改變),如果其他線程嘗試獲取這個鎖,偏向鎖將會膨脹為輕量鎖。
優(yōu)點(diǎn):在只有一個線程使用鎖的時候獲取和退出鎖沒有任何花費(fèi)
缺點(diǎn):鎖競爭激烈會很快升級為輕量鎖,那么維持偏向鎖的過程就是在浪費(fèi)計(jì)算機(jī)資源。(不過因?yàn)?code>偏向鎖本身就很輕量,因此浪費(fèi)的資源并不多)
小結(jié):只有一個線程使用鎖的情況下,synchronized使用的鎖為偏向鎖。
如果鎖競爭激烈,可以通過配置JDK禁用偏向鎖。
2.2 輕量鎖
一把鎖不止一個線程使用,則偏向鎖膨脹為輕量鎖
表現(xiàn):線程獲取輕量鎖時,會直接用CAS修改對象頭里鎖的記錄,如果修改失敗,代表此時鎖存在多個線程的競爭,輕量鎖將會膨脹為重量鎖。
優(yōu)點(diǎn):在線程之間使用鎖不存在競爭時,一次CAS操作就能獲取和退出鎖
缺點(diǎn):與偏向鎖類似
小結(jié):只要一把鎖不止一個線程獲取過,偏向鎖就會膨脹為輕量鎖。
2.3 重量鎖
一把鎖存在多線程競爭,則輕量鎖開始自旋,自旋一定次數(shù)后仍沒獲取鎖,則膨脹為重量鎖(存在競爭時,輕量鎖雖然會先自旋,但是最終往往都會膨脹為重量鎖)
表現(xiàn):線程獲取重量鎖時,如果獲取失?。存i已被其他線程獲?。瑒t使用自適應(yīng)自旋鎖,自旋一定次數(shù)后仍沒獲取鎖,則進(jìn)入阻塞隊(duì)列等待。
優(yōu)點(diǎn):未獲取到的鎖進(jìn)入阻塞隊(duì)列,節(jié)約CPU資源。(好吧感覺其實(shí)是沒有啥優(yōu)點(diǎn))
缺點(diǎn):重量鎖是通過對象內(nèi)部的監(jiān)視器(monitor)實(shí)現(xiàn),其中monitor的本質(zhì)是依賴于底層操作系統(tǒng)的Mutex Lock實(shí)現(xiàn),操作系統(tǒng)實(shí)現(xiàn)線程之間的切換需要從用戶態(tài)到內(nèi)核態(tài)的切換,切換成本非常高。
小結(jié):只要一把鎖存在多線程競爭,輕量鎖就會膨脹為重量鎖。
自旋鎖
synchronized的輕量鎖,重量鎖,使用了自適應(yīng)自旋鎖進(jìn)行性能優(yōu)化
首先介紹自旋鎖
表現(xiàn):線程獲取鎖失敗后,不會進(jìn)入阻塞等待,而是再次嘗試去獲取鎖,如此反復(fù),直到獲取到鎖,或者自旋結(jié)束那么會阻塞等待。
解決問題:在某些場景下,線程持有鎖的時間非常短。在線程獲取鎖失敗后,如果線程進(jìn)入阻塞將會帶來線程上下文的切換,上下文切換的時間可能反而高于線程反復(fù)嘗試獲取鎖的時間。
此時線程原地等待去重復(fù)獲取鎖。反而在性能上更有優(yōu)勢。
缺點(diǎn):
單核CPU沒有線程并行,反復(fù)嘗試會導(dǎo)致進(jìn)程無法繼續(xù)運(yùn)行。重復(fù)嘗試導(dǎo)致了CPU的占用,如果CPU資源緊張的話反而會性能下降如果鎖的競爭時間過長,不僅沒有性能提升,還浪費(fèi)了大量CPU資源。
優(yōu)化:使用自適應(yīng)自旋鎖。自適應(yīng)自旋鎖會根據(jù)之前的鎖獲取記錄,優(yōu)化調(diào)整自旋時間,避免造成不必要的自旋。
三 具體synchronized流程

總結(jié)
以上所述是小編給大家介紹的Java中synchronized關(guān)鍵字引出的多種鎖 問題 ,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
如果你覺得本文對你有幫助,歡迎轉(zhuǎn)載,煩請注明出處,謝謝!
- Java的Synchronized關(guān)鍵字學(xué)習(xí)指南(全面 & 詳細(xì))
- 深入分析JAVA Synchronized關(guān)鍵字
- Java synchronized關(guān)鍵字使用方式及特性解析
- Java synchronized關(guān)鍵字和Lock接口實(shí)現(xiàn)原理
- Java多線程并發(fā)編程 Synchronized關(guān)鍵字
- 深入講解java線程與synchronized關(guān)鍵字
- 實(shí)例解析Java中的synchronized關(guān)鍵字與線程安全問題
- Java中synchronized關(guān)鍵字修飾方法同步的用法詳解
- Java多線程編程中synchronized關(guān)鍵字的基礎(chǔ)用法講解
- 詳解Java中synchronized關(guān)鍵字的死鎖和內(nèi)存占用問題
- 舉例講解Java中synchronized關(guān)鍵字的用法
- Java多線程之synchronized關(guān)鍵字的使用
相關(guān)文章
JdbcTemplate操作數(shù)據(jù)庫的具體方法
這篇文章主要介紹了JdbcTemplate操作數(shù)據(jù)庫的具體操作方法,準(zhǔn)備工作需要大家先導(dǎo)入相關(guān)的jar包,建個數(shù)據(jù)庫,具體操作方法跟隨小編一起看看吧2022-03-03
Java 集合實(shí)現(xiàn)分頁的方法(業(yè)務(wù)代碼實(shí)現(xiàn)分頁)
在Java開發(fā)中,有些場景比較復(fù)雜,受限制,不好在sql查詢層面實(shí)現(xiàn)分頁,需要在查詢的list結(jié)果后,將list分頁返回,如何實(shí)現(xiàn)呢,帶著這個問題一起通過本文學(xué)習(xí)吧2025-02-02
java?數(shù)組實(shí)現(xiàn)學(xué)生成績統(tǒng)計(jì)教程
這篇文章主要介紹了java?數(shù)組實(shí)現(xiàn)學(xué)生成績統(tǒng)計(jì)教程,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-12-12
Spring ApplicationListener源碼解析
這篇文章主要為大家介紹了Spring ApplicationListener源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01
使用springboot時,解決@Scheduled定時器遇到的問題
這篇文章主要介紹了使用springboot時,解決@Scheduled定時器遇到的問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-11-11
Java中八種基本數(shù)據(jù)類型的默認(rèn)值
這篇文章主要介紹了Java中八種基本數(shù)據(jù)類型的默認(rèn)值 的相關(guān)資料,需要的朋友可以參考下2016-07-07
基于rocketmq的有序消費(fèi)模式和并發(fā)消費(fèi)模式的區(qū)別說明
這篇文章主要介紹了基于rocketmq的有序消費(fèi)模式和并發(fā)消費(fèi)模式的區(qū)別說明,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-06-06
Springboot項(xiàng)目中內(nèi)嵌sqlite數(shù)據(jù)庫的配置流程
這篇文章主要介紹了Springboot項(xiàng)目中內(nèi)嵌sqlite數(shù)據(jù)庫的配置流程,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-06-06

