溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Java鎖怎么理解

發(fā)布時(shí)間:2021-12-01 09:49:55 來源:億速云 閱讀:118 作者:iii 欄目:編程語言

本篇內(nèi)容主要講解“Java鎖怎么理解”,感興趣的朋友不妨來看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“Java鎖怎么理解”吧!

自旋?

Java鎖怎么理解

Java鎖怎么理解

自旋鎖

如果此時(shí)拿不到鎖,它不馬上進(jìn)入阻塞狀態(tài),而愿意等待一段時(shí)間。

如果循環(huán)一定的次數(shù)還拿不到鎖,那么它才會(huì)進(jìn)入阻塞的狀態(tài),循環(huán)的次數(shù)是可以人為指定的。

  •  自旋鎖?

有一天去全家買咖啡,服務(wù)員說真不巧,前面咖啡機(jī)壞了,現(xiàn)在正在修,要等10分鐘喔,恰好沒什么急事,那就等吧,坐到一邊休息區(qū)等10分鐘(其它什么事都沒做)。介就是自旋鎖~(自己空轉(zhuǎn)一會(huì)兒)

覺得有點(diǎn)浪費(fèi)時(shí)間?如果你等了15分鐘,還沒修好,那你可能不愿意繼續(xù)等下去了(15分鐘就是設(shè)定的自旋等待的最大時(shí)間)

Java鎖怎么理解

Java鎖怎么理解

上面說自旋鎖循環(huán)的次數(shù)是人為指定的,而自適應(yīng)旋轉(zhuǎn)鎖,就厲害了,它不需要人為指定循環(huán)次數(shù),它自己本身會(huì)判斷要循環(huán)幾次,而且每個(gè)線程可能循環(huán)的次數(shù)也是不一樣的。

如果這個(gè)線程之前拿到過鎖,或者經(jīng)常拿到一個(gè)鎖,那它自己判斷下來再次拿到這個(gè)鎖的概率很大,循環(huán)次數(shù)就大一些;如果這個(gè)線程之前沒拿到過這個(gè)鎖,那它就沒把握了,怕消耗CPU,循環(huán)次數(shù)就小一點(diǎn)。

它解決的是“鎖競(jìng)爭(zhēng)時(shí)間不確定”的問題,但也不一定它自己設(shè)定的一定合適。

  •  自適應(yīng)旋轉(zhuǎn)鎖?

還是前面去全家等咖啡的栗子吧~ 要是等到5分鐘,還沒修好,你目測(cè)10分鐘里也修不好,就不再等下去了(循環(huán)次數(shù)?。?;

要是等了10分鐘了,服務(wù)員說非常抱歉,快了快了,再1分鐘就可以用了,你也還不急,都已經(jīng)等了10分鐘了,就多等一會(huì)兒嘛(循環(huán)次數(shù)大)。

Java鎖怎么理解

Java鎖怎么理解

這個(gè)是自旋鎖的簡(jiǎn)單代碼實(shí)現(xiàn):

public class SpinLock {      private AtomicReference<Thread> cas = new AtomicReference<Thread>();      public void lock() {          Thread current = Thread.currentThread();          // 利用CAS          while (!cas.compareAndSet(null, current)) {              // DO nothing          }      }      public void unlock() {          Thread current = Thread.currentThread();          cas.compareAndSet(current, null);      }  }

稍微分析下~

  •  lock()方法利用CAS,當(dāng)?shù)谝粋€(gè)線程A獲取鎖的時(shí)候,能夠成功獲取到,不會(huì)進(jìn)入while循環(huán);

  •  如果此時(shí)線程A沒有釋放鎖,另一個(gè)線程B又來獲取鎖,此時(shí)由于不滿足CAS,所以就會(huì)進(jìn)入while循環(huán);

  •  然后線程B會(huì)不斷判斷是否滿足CAS,直到A線程調(diào)用unlock方法釋放了該鎖,它才能獲取鎖。   

Java鎖怎么理解

Java鎖怎么理解

  • 主要存在以下問題:

  1.  如果某個(gè)線程持有鎖的時(shí)間過長(zhǎng),就會(huì)導(dǎo)致其它等待獲取鎖的線程進(jìn)入循環(huán)等待,消耗CPU。使用不當(dāng)會(huì)造成CPU使用率極高。

  2.  本身無法保證公平性,即無法滿足等待時(shí)間最長(zhǎng)的線程優(yōu)先獲取鎖。不公平的鎖就會(huì)存在“線程饑餓”問題。

  3.  無法保證可重入性?;谧孕i,可以實(shí)現(xiàn)具備公平性和可重入性質(zhì)的鎖。

后面這幾個(gè)以后有空再詳細(xì)來說~

自旋鎖 Vs 阻塞鎖

Java鎖怎么理解

Java鎖怎么理解

  •  阻塞的栗子~

去一個(gè)熱門飯店吃飯,到了門口一看,門口的座位坐滿了人&hellip;&hellip;這咋整&hellip;&hellip;服務(wù)員說,您可以先拿個(gè)號(hào)~小票上掃個(gè)二維碼,關(guān)注咱們,輪到您了,服務(wù)號(hào)里就會(huì)有提示噠~(很熟悉是不是?)

然后你就先取了號(hào)去逛逛周圍小店去了,等輪到你了,手機(jī)里收到一條服務(wù)提醒消息,到你啦~這時(shí)你再去,就可以進(jìn)店了。

這就是阻塞的過程~

那自旋呢?

就是你自己其它事情都不做,等在那里,就像去超市排隊(duì)結(jié)賬一樣,你走開的話是沒有人會(huì)通知你的,只能重新排隊(duì),需要自己時(shí)刻檢查有沒有排到(能不能訪問到共享資源)。

這里插播一下:

阻塞或喚醒一個(gè)Java線程需要操作系統(tǒng)切換CPU狀態(tài)來完成,這種狀態(tài)轉(zhuǎn)換需要耗費(fèi)處理器時(shí)間。

來看看自旋和阻塞的比較~

Java鎖怎么理解

Java鎖怎么理解

Java鎖怎么理解

Java鎖怎么理解

只升不降的鎖狀態(tài)

鎖主要存在四種狀態(tài):“無鎖狀態(tài)、偏向鎖狀態(tài)、輕量級(jí)鎖狀態(tài)、重量級(jí)鎖狀態(tài)”。

其實(shí)這四種狀態(tài)都不是Java語言中的鎖,而是Jvm為了提高鎖的獲取與釋放效率而做的優(yōu)化(使用synchronized時(shí))。

它們會(huì)隨著競(jìng)爭(zhēng)的激烈而逐漸升級(jí),并且是不可逆的升級(jí)。

升級(jí)過程是這樣的:

  •  偏向鎖 -> 輕量級(jí)鎖 -> 重量級(jí)鎖

Java鎖怎么理解

Java鎖怎么理解

關(guān)于無鎖~

如果一個(gè)方法本來就不涉及共享數(shù)據(jù),那它自然就無須任何同步措施去保證正確性,因此會(huì)有一些代碼天生就是線程安全的。

它沒有對(duì)資源進(jìn)行鎖定,所有的線程都能訪問并修改同一個(gè)資源,但同時(shí)只有一個(gè)線程能修改成功。

CAS算法 即compare and swap(比較與交換),就是有名的無鎖算法。

Java鎖怎么理解

Java鎖怎么理解

Java鎖怎么理解

Java鎖怎么理解

Java鎖怎么理解

狀態(tài)還是詳細(xì)比較下吧~

Java鎖怎么理解

  •  知道你想要栗子

你經(jīng)常去一家店坐在同一個(gè)位置吃飯,老板已經(jīng)記住你啦,每次你去的時(shí)候,只要店里客人不多,老板都會(huì)給你留著那個(gè)座位,這個(gè)座位就是你的“偏向鎖”,每次只有你這一個(gè)線程用。

有一天你去的時(shí)候,店里已經(jīng)坐滿了,你的位置也被別人坐了,你只能等著(進(jìn)入競(jìng)爭(zhēng)狀態(tài)),這時(shí)那個(gè)座位就升級(jí)到“輕量級(jí)鎖”了。

要是那個(gè)座位特別好(臨窗風(fēng)景最佳,能隔江賞月~)每次你到的時(shí)候,都有其他好幾個(gè)人也要去搶那個(gè)位置,沒坐到那個(gè)位置就不吃飯了>_< 那時(shí)那個(gè)座位就升級(jí)到“重量級(jí)鎖”了。

是不是好理解啦?

共享 or 獨(dú)享?

Java鎖怎么理解

還是專業(yè)地講下概念~(手機(jī)上請(qǐng)點(diǎn)擊圖片放大看看~)

Java鎖怎么理解

Java鎖怎么理解 

Java鎖怎么理解

Java鎖怎么理解

  • 還有栗子~

每個(gè)禮拜小組的各個(gè)成員要共同填一份周報(bào)表格,

要是每個(gè)人打開的時(shí)候,可以加一個(gè)寫鎖,即你在寫的時(shí)候,別人不能修改,這就是獨(dú)享鎖(寫鎖);

但是這份表格大家可以同時(shí)打開,看到表格內(nèi)容(讀取數(shù)據(jù)),正在改數(shù)據(jù)的人可以對(duì)這份表格加上共享鎖,那這個(gè)鎖就是共享鎖。

到此,相信大家對(duì)“Java鎖怎么理解”有了更深的了解,不妨來實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI