新聞中心
這篇文章主要介紹“Java中的鎖有哪些”,在日常操作中,相信很多人在Java中的鎖有哪些問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Java中的鎖有哪些”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!
創(chuàng)新互聯(lián)成立與2013年,先為東海等服務(wù)建站,東海等地企業(yè),進(jìn)行企業(yè)商務(wù)咨詢服務(wù)。為東海企業(yè)網(wǎng)站制作PC+手機(jī)+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問題。
一、鎖的類型
Java中的鎖從宏觀來分,分為悲觀鎖、和樂觀鎖。
樂觀鎖
樂觀鎖是一種樂觀思想,即認(rèn)為讀多寫少,遇到并發(fā)寫的可能性低,每次去拿數(shù)據(jù)的時候都認(rèn)為別人不會修改,所以不會上鎖,但是在更新的時候會判斷一下在此期間別人有沒有去更新這個數(shù)據(jù),采取在寫時先讀出當(dāng)前版本號,然后加鎖操作(比較跟上一次的版本號,如果一樣則更新),如果失敗則要重復(fù)讀-比較-寫的操作。
java中的樂觀鎖基本都是通過CAS操作實現(xiàn)的,CAS是一種更新的原子操作,比較當(dāng)前值跟傳入值是否一樣,一樣則更新,否則失敗。
悲觀鎖
悲觀鎖是就是悲觀思想,即認(rèn)為寫多,遇到并發(fā)寫的可能性高,每次去拿數(shù)據(jù)的時候都認(rèn)為別人會修改,所以每次在讀寫數(shù)據(jù)的時候都會上鎖,這樣別人想讀寫這個數(shù)據(jù)就會block直到拿到鎖。java中的悲觀鎖就是synchronized,AQS框架下的鎖則是先嘗試cas樂觀鎖去獲取鎖,獲取不到,才會轉(zhuǎn)換為悲觀鎖,如RetreenLock。
二、Java線程阻塞的代價
Java的線程是映射到操作系統(tǒng)原生線程之上的,如果要阻塞或喚醒一個線程就需要操作系統(tǒng)介入,需要在用戶態(tài)與核心態(tài)之間切換,這種切換會消耗大量的系統(tǒng)資源,因為用戶態(tài)與內(nèi)核態(tài)都有各自專用的內(nèi)存空間,專用的寄存器等,用戶態(tài)切換至內(nèi)核態(tài)需要傳遞給許多變量、參數(shù)給內(nèi)核,內(nèi)核也需要保護(hù)好用戶態(tài)在切換時的一些寄存器值、變量等,以便內(nèi)核態(tài)調(diào)用結(jié)束后切換回用戶態(tài)繼續(xù)工作。
如果線程狀態(tài)切換是一個高頻操作時,這將會消耗很多CPU處理時間;
如果對于那些需要同步的簡單的代碼塊,獲取鎖掛起操作消耗的時間比用戶代碼執(zhí)行的時間還要長,這種同步策略的選擇就很不明智。
synchronized會導(dǎo)致爭用不到鎖的線程進(jìn)入阻塞狀態(tài),所以說它是Java語言中一個重量級的同步操縱,被稱為重量級鎖,為了緩解上述性能問題,JVM從1.5開始,引入了輕量鎖與偏向鎖,默認(rèn)啟用了自旋鎖,他們都屬于樂觀鎖。
明確java線程切換的代價,是理解java中各種鎖的優(yōu)缺點的基礎(chǔ)之一。
三、markword
markword是java對象數(shù)據(jù)結(jié)構(gòu)中的一部分,對象的markword和java各種類型的鎖密切相關(guān);
markword數(shù)據(jù)的長度在32位和64位的虛擬機(jī)(未開啟壓縮指針)中分別為32bit和64bit,它的最后2bit是鎖狀態(tài)標(biāo)志位,用來標(biāo)記當(dāng)前對象的狀態(tài),對象的所處的狀態(tài),決定了markword存儲的內(nèi)容,如下表所示:
狀態(tài) | 標(biāo)志位 | 存儲內(nèi)容 |
---|---|---|
未鎖定 | 01 | 對象哈希碼、對象分代年齡 |
輕量級鎖定 | 00 | 指向鎖記錄的指針 |
膨脹(重量級鎖定) | 10 | 執(zhí)行重量級鎖定的指針 |
GC標(biāo)記 | 11 | 空(不需要記錄信息) |
可偏向 | 01 | 偏向線程ID、偏向時間戳、對象分代年齡 |
32位虛擬機(jī)在不同狀態(tài)下markword結(jié)構(gòu)如下所示:
鎖狀態(tài) | 25bit | 4bit | 1bit | 2bit | |
23bit | 2bit | 是否是偏向鎖 | 鎖標(biāo)志位 | ||
輕量級鎖 | 指向棧中鎖記錄的指針 | 00 | |||
重量級鎖 | 指向互斥量(重量級鎖)的指針 | 10 | |||
GC標(biāo)記 | 空 | 11 | |||
偏向鎖 | 線程ID | Epoch | 對象分代年齡 | 1 | 01 |
無鎖 | 對象的hashCode | 對象分代年齡0 | 0 | 01 |
小結(jié)
前面提到了java的4種鎖,他們分別是重量級鎖、自旋鎖、輕量級鎖和偏向鎖,不同的鎖有不同特點,每種鎖只有在其特定的場景下,才會有出色的表現(xiàn),java中沒有哪種鎖能夠在所有情況下都能有出色的效率,引入這么多鎖的原因就是為了應(yīng)對不同的情況。
重量級鎖是悲觀鎖的一種,自旋鎖、輕量級鎖與偏向鎖屬于樂觀鎖。
到此,關(guān)于“Java中的鎖有哪些”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>
網(wǎng)站欄目:Java中的鎖有哪些
URL地址:http://fisionsoft.com.cn/article/jojosj.html