最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

AQS底層原理連環(huán)相扣系列鎖面試題分析

csdn   發(fā)布時(shí)間:2022-05-19 16:19:39   作者:Q.E.D.   我要評(píng)論
面試中,問鎖主要是兩方面:鎖的日常使用場景 + 鎖原理,鎖的日常使用場景主要考察對(duì)鎖 API 的使用熟練度,看看你是否真的使用過這些 API,而不是紙上談兵,鎖原理主要就是問 AQS 底層的源碼原理了,接下來我們一起看一看關(guān)于鎖的常見源碼面試題

引導(dǎo)語

面試中,問鎖主要是兩方面:鎖的日常使用場景 + 鎖原理,鎖的日常使用場景主要考察對(duì)鎖 API 的使用熟練度,看看你是否真的使用過這些 API,而不是紙上談兵,鎖原理主要就是問 AQS 底層的源碼原理了,如果問得更加深入的話,可能會(huì)現(xiàn)場讓你實(shí)現(xiàn)一個(gè)簡單的鎖,簡單要求的會(huì)讓你直接使用 AQS API,復(fù)雜要求的可能需要重新實(shí)現(xiàn) AQS。

1、AQS 相關(guān)面試題

1.1、說說自己對(duì) AQS 的理解?

答:回答這樣的問題的時(shí)候,面試官主要考察的是你對(duì) AQS 的知識(shí)有沒有系統(tǒng)的整理,建議回答的方向是由大到小,由全到細(xì),由使用到原理。

如果和面試官面對(duì)面的話,可以邊說邊畫出我們?cè)?AQS 源碼解析上中畫出的整體架構(gòu)圖,并且可以這么說:

AQS 是一個(gè)鎖框架,它定義了鎖的實(shí)現(xiàn)機(jī)制,并開放出擴(kuò)展的地方,讓子類去實(shí)現(xiàn),比如我們?cè)?lock 的時(shí)候,AQS 開放出 state 字段,讓子類可以根據(jù) state 字段來決定是否能夠獲得鎖,對(duì)于獲取不到鎖的線程 AQS 會(huì)自動(dòng)進(jìn)行管理,無需子類鎖關(guān)心,這就是 lock 時(shí)鎖的內(nèi)部機(jī)制,封裝的很好,又暴露出子類鎖需要擴(kuò)展的地方;

AQS 底層是由同步隊(duì)列 + 條件隊(duì)列聯(lián)手組成,同步隊(duì)列管理著獲取不到鎖的線程的排隊(duì)和釋放,條件隊(duì)列是在一定場景下,對(duì)同步隊(duì)列的補(bǔ)充,比如獲得鎖的線程從空隊(duì)列中拿數(shù)據(jù),肯定是拿不到數(shù)據(jù)的,這時(shí)候條件隊(duì)列就會(huì)管理該線程,使該線程阻塞;

AQS 圍繞兩個(gè)隊(duì)列,提供了四大場景,分別是:獲得鎖、釋放鎖、條件隊(duì)列的阻塞,條件隊(duì)列的喚醒,分別對(duì)應(yīng)著 AQS 架構(gòu)圖中的四種顏色的線的走向。

以上三點(diǎn)都是 AQS 全局方面的描述,接著你可以問問面試官要不要說細(xì)一點(diǎn),可以的話,按照 AQS 源碼解析上下兩篇,把四大場景都說一下就好了。

這樣說的好處是很多的:

面試的主動(dòng)權(quán)把握在自己手里,而且都是自己掌握的知識(shí)點(diǎn);

由全到細(xì)的把 AQS 全部說完,會(huì)給面試官一種你對(duì) AQS 了如指掌的感覺,再加上全部說完耗時(shí)會(huì)很久,面試時(shí)間又很有限,面試官就不會(huì)再問關(guān)于 AQS 一些刁鉆的問題了,這樣 AQS 就可以輕松過關(guān)。

當(dāng)然如果你對(duì) AQS 了解的不是很深,那么就大概回答下 AQS 的大體架構(gòu)就好了,就不要說的特別細(xì),免得給自己挖坑。

1.2、多個(gè)線程通過鎖請(qǐng)求共享資源,獲取不到鎖的線程怎么辦?

答:加鎖(排它鎖)主要分為以下四步:

嘗試獲得鎖,獲得鎖了直接返回,獲取不到鎖的走到 2;

用 Node 封裝當(dāng)前線程,追加到同步隊(duì)列的隊(duì)尾,追加到隊(duì)尾時(shí),又有兩步,如 3 和 4;

自旋 + CAS 保證前一個(gè)節(jié)點(diǎn)的狀態(tài)置為 signal;

阻塞自己,使當(dāng)前線程進(jìn)入等待狀態(tài)。

獲取不到鎖的線程會(huì)進(jìn)行 2、3、4 步,最終會(huì)陷入等待狀態(tài),這個(gè)描述的是排它鎖。

1.3、問題 1.2 中,排它鎖和共享鎖的處理機(jī)制是一樣的么?

答:排它鎖和共享鎖在問題 1.2 中的 2、3、4 步驟都是一樣的, 不同的是在于第一步,線程獲得排它鎖的時(shí)候,僅僅把自己設(shè)置為同步隊(duì)列的頭節(jié)點(diǎn)即可,但如果是共享鎖的話,還會(huì)去喚醒自己的后續(xù)節(jié)點(diǎn),一起來獲得該鎖。

1.4、共享鎖和排它鎖的區(qū)別?

答:排它鎖的意思是同一時(shí)刻,只能有一個(gè)線程可以獲得鎖,也只能有一個(gè)線程可以釋放鎖。

共享鎖可以允許多個(gè)線程獲得同一個(gè)鎖,并且可以設(shè)置獲取鎖的線程數(shù)量,共享鎖之所以能夠做到這些,是因?yàn)榫€程一旦獲得共享鎖,把自己設(shè)置成同步隊(duì)列的頭節(jié)點(diǎn)后,會(huì)自動(dòng)的去釋放頭節(jié)點(diǎn)后等待獲取共享鎖的節(jié)點(diǎn),讓這些等待節(jié)點(diǎn)也一起來獲得共享鎖,而排它鎖就不會(huì)這么干。

1.5、排它鎖和共享鎖說的是加鎖時(shí)的策略,那么鎖釋放時(shí)有排它鎖和共享鎖的策略么?

答:是的,排它鎖和共享鎖,主要體現(xiàn)在加鎖時(shí),多個(gè)線程能否獲得同一個(gè)鎖。

但在鎖釋放時(shí),是沒有排它鎖和共享鎖的概念和策略的,概念僅僅針對(duì)鎖獲取。

1.6、描述下同步隊(duì)列?

答:同步隊(duì)列底層的數(shù)據(jù)結(jié)構(gòu)就是雙向的鏈表,節(jié)點(diǎn)叫做 Node,頭節(jié)點(diǎn)叫做 head,尾節(jié)點(diǎn)叫做 tail,節(jié)點(diǎn)和節(jié)點(diǎn)間的前后指向分別叫做 prev、next,如果是面對(duì)面面試的話,可以畫一下 AQS 整體架構(gòu)圖中的同步隊(duì)列。

同步隊(duì)列的作用:阻塞獲取不到鎖的線程,并在適當(dāng)時(shí)機(jī)釋放這些線程。

實(shí)現(xiàn)的大致過程:當(dāng)多個(gè)線程都來請(qǐng)求鎖時(shí),某一時(shí)刻有且只有一個(gè)線程能夠獲得鎖(排它鎖),那么剩余獲取不到鎖的線程,都會(huì)到同步隊(duì)列中去排隊(duì)并阻塞自己,當(dāng)有線程主動(dòng)釋放鎖時(shí),就會(huì)從同步隊(duì)列中頭節(jié)點(diǎn)開始釋放一個(gè)排隊(duì)的線程,讓線程重新去競爭鎖。

1.7、描述下線程入、出同步隊(duì)列的時(shí)機(jī)和過程?

答:(排它鎖為例)從 AQS 整體架構(gòu)圖中,可以看出同步隊(duì)列入隊(duì)和出隊(duì)都是有兩個(gè)箭頭指向,所以入隊(duì)和出隊(duì)的時(shí)機(jī)各有兩個(gè)。

同步隊(duì)列入隊(duì)時(shí)機(jī):

多個(gè)線程請(qǐng)求鎖,獲取不到鎖的線程需要到同步隊(duì)列中排隊(duì)阻塞;

條件隊(duì)列中的節(jié)點(diǎn)被喚醒,會(huì)從條件隊(duì)列中轉(zhuǎn)移到同步隊(duì)列中來。

同步隊(duì)列出隊(duì)時(shí)機(jī):

鎖釋放時(shí),頭節(jié)點(diǎn)出隊(duì);

獲得鎖的線程,進(jìn)入條件隊(duì)列時(shí),會(huì)釋放鎖,同步隊(duì)列頭節(jié)點(diǎn)開始競爭鎖。

四個(gè)時(shí)機(jī)的過程可以參考 AQS 源碼解析,1 參考 acquire 方法執(zhí)行過程,2 參考 signal 方法,3 參考 release 方法,4 參考 await 方法。

1.8、為什么 AQS 有了同步隊(duì)列之后,還需要條件隊(duì)列?

答:的確,一般情況下,我們只需要有同步隊(duì)列就好了,但在上鎖后,需要操作隊(duì)列的場景下,一個(gè)同步隊(duì)列就搞不定了,需要條件隊(duì)列進(jìn)行功能補(bǔ)充,比如當(dāng)隊(duì)列滿時(shí),執(zhí)行 put 操作的線程會(huì)進(jìn)入條件隊(duì)列等待,當(dāng)隊(duì)列空時(shí),執(zhí)行 take 操作的線程也會(huì)進(jìn)入條件隊(duì)列中等待,從一定程度上來看,條件隊(duì)列是對(duì)同步隊(duì)列的場景功能補(bǔ)充。

1.9、描述一下條件隊(duì)列中的元素入隊(duì)和出隊(duì)的時(shí)機(jī)和過程?

答:

入隊(duì)時(shí)機(jī):執(zhí)行 await 方法時(shí),當(dāng)前線程會(huì)釋放鎖,并進(jìn)入到條件隊(duì)列。

出隊(duì)時(shí)機(jī):執(zhí)行 signal、signalAll 方法時(shí),節(jié)點(diǎn)會(huì)從條件隊(duì)列中轉(zhuǎn)移到同步隊(duì)列中。

具體的執(zhí)行過程,可以參考源碼解析中 await 和 signal 方法。

1.10、描述一下條件隊(duì)列中的節(jié)點(diǎn)轉(zhuǎn)移到同步隊(duì)列中去的時(shí)機(jī)和過程?

答:時(shí)機(jī):當(dāng)有線程執(zhí)行 signal、signalAll 方法時(shí),從條件隊(duì)列的頭節(jié)點(diǎn)開始,轉(zhuǎn)移到同步隊(duì)列中去。

過程主要是以下幾步:

找到條件隊(duì)列的頭節(jié)點(diǎn),頭節(jié)點(diǎn) next 屬性置為 null,從條件隊(duì)列中移除了;

頭節(jié)點(diǎn)追加到同步隊(duì)列的隊(duì)尾;

頭節(jié)點(diǎn)狀態(tài)(waitStatus)從 CONDITION 修改成 0(初始化狀態(tài));

將節(jié)點(diǎn)的前一個(gè)節(jié)點(diǎn)狀態(tài)置為 SIGNAL。

1.11、線程入條件隊(duì)列時(shí),為什么需要釋放持有的鎖?

答:原因很簡單,如果當(dāng)前線程不釋放鎖,一旦跑去條件隊(duì)里中阻塞了,后續(xù)所有的線程都無法獲得鎖,正確的場景應(yīng)該是:當(dāng)前線程釋放鎖,到條件隊(duì)列中去阻塞后,其他線程仍然可以獲得當(dāng)前鎖。

2、AQS 子類鎖面試題

2.1、你在工作中如何使用鎖的,寫一個(gè)看一看?

答:這個(gè)照實(shí)說就好了

2.2、如果我要自定義鎖,大概的實(shí)現(xiàn)思路是什么樣子的?

答:現(xiàn)在有很多類似的問題,比如讓你自定義隊(duì)列,自定義鎖等等,面試官其實(shí)并不是想讓我們重新造一個(gè)輪子,而是想考察一下我們對(duì)于隊(duì)列、鎖理解的深度,我們只需要選擇自己最熟悉的 API 描述一下就好了,所以這題我們可以選擇 ReentrantLock 來描述一下實(shí)現(xiàn)思路:

新建內(nèi)部類繼承 AQS,并實(shí)現(xiàn) AQS 的 tryAcquire 和 tryRelease 兩個(gè)方法,在 tryAcquire 方法里面實(shí)現(xiàn)控制能否獲取鎖,比如當(dāng)同步器狀態(tài) state 是 0 時(shí),即可獲得鎖,在 tryRelease 方法里面控制能否釋放鎖,比如將同步器狀態(tài)遞減到 0 時(shí),即可釋放鎖;

對(duì)外提供 lock、release 兩個(gè)方法,lock 表示獲得鎖的方法,底層調(diào)用 AQS 的 acquire 方法,release 表示釋放鎖的方法,底層調(diào)用 AQS 的 release 方法。

2.3、描述 ReentrantLock 兩大特性:可重入性和公平性?底層分別如何實(shí)現(xiàn)的?

答:可重入性說的是線程可以對(duì)共享資源重復(fù)加鎖,對(duì)應(yīng)的,釋放時(shí)也可以重復(fù)釋放,對(duì)于 ReentrantLock 來說,在獲得鎖的時(shí)候,state 會(huì)加 1,重復(fù)獲得鎖時(shí),不斷的對(duì) state 進(jìn)行遞增即可,比如目前 state 是 4,表示線程已經(jīng)對(duì)共享資源加鎖了 4 次,線程每次釋放共享資源的鎖時(shí),state 就會(huì)遞減 1,直到遞減到 0 時(shí),才算真正釋放掉共享資源。

公平性和非公平指的是同步隊(duì)列中的線程得到鎖的機(jī)制,如果同步隊(duì)列中的線程按照阻塞的順序得到鎖,我們稱之為公平的,反之是非公平的,公平的底層實(shí)現(xiàn)是 ReentrantLock 的 tryAcquire 方法(調(diào)用的是 AQS 的 hasQueuedPredecessors 方法)里面實(shí)現(xiàn)的,要釋放同步隊(duì)列的節(jié)點(diǎn)時(shí)(或者獲得鎖時(shí)),判斷當(dāng)前線程節(jié)點(diǎn)是不是同步隊(duì)列的頭節(jié)點(diǎn)的后一個(gè)節(jié)點(diǎn),如果是就釋放,不是則不能釋放,通過這種機(jī)制,保證同步隊(duì)列中的線程得到鎖時(shí),是按照從頭到尾的順序的。

2.4、如果一個(gè)線程需要等待一組線程全部執(zhí)行完之后再繼續(xù)執(zhí)行,有什么好的辦法么?是如何實(shí)現(xiàn)的?

答:CountDownLatch 就提供了這樣的機(jī)制,比如一組線程有 5 個(gè),只需要在初始化 CountDownLatch 時(shí),給同步器的 state 賦值為 5,主線程執(zhí)行 CountDownLatch.await ,子線程都執(zhí)行 CountDownLatch.countDown 即可。

2.5、Atomic 原子操作類可以保證線程安全,如果操作的對(duì)象是自定義的類的話,要如何做呢?

答: Java 為這種情況提供了一個(gè) API:AtomicReference,AtomicReference 類可操作的對(duì)象是個(gè)泛型,所以支持自定義類。

3、總結(jié)

關(guān)于 AQS 和鎖場景的面試題,其實(shí)網(wǎng)上也很多,各個(gè)大廠出的題目也都不一樣,但考察問題的本質(zhì)都是一致的,如果把 AQS 架構(gòu)圖中,AQS 的組成和四種顏色箭頭的發(fā)起時(shí)機(jī),調(diào)用過程都弄清楚了,回答 AQS 的各種問題都會(huì)游刃有余。

以上就是AQS底層原理連環(huán)相扣系列鎖面試題分析的詳細(xì)內(nèi)容,更多關(guān)于AQS原理連環(huán)相扣系列鎖面試分析的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論

讷河市| 叙永县| 阳东县| 新民市| 博客| 上杭县| 岳普湖县| 通山县| 旬邑县| 肥乡县| 临潭县| 新化县| 海阳市| 印江| 封开县| 新巴尔虎右旗| 达拉特旗| 重庆市| 龙南县| 静宁县| 大丰市| 瑞丽市| 九龙城区| 肥东县| 湘潭县| 宝兴县| 赫章县| 龙江县| 乌鲁木齐县| 琼海市| 大埔县| 长春市| 新疆| 溆浦县| 陈巴尔虎旗| 于田县| 宣威市| 建始县| 永清县| 绥德县| 武冈市|