亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

首頁(yè) Java Java面試題 小白也能與BAT面試官對(duì)線:CAS

小白也能與BAT面試官對(duì)線:CAS

Aug 24, 2023 pm 03:09 PM
java面試題

前言

Java並發(fā)程式設(shè)計(jì)系列番外篇C A S(Compare and swap),文章風(fēng)格依然是圖文並茂,通俗易懂,讓讀者也能與面試官瘋狂對(duì)線。

C A S作為並發(fā)程式設(shè)計(jì)必不可少的基礎(chǔ)知識(shí),面試時(shí)C A S也是個(gè)高頻考點(diǎn),所以說(shuō)C A S是必知必會(huì),本文將帶讀者們深入理解C A S。

大綱

小白也能與BAT面試官對(duì)線:CAS

#C A S基本概念

C A S(compareAndSwap)也叫比較交換,是一種無(wú)鎖原子演算法,映射到作業(yè)系統(tǒng)就是一條cmpxchg硬體彙編指令(保證原子性),其作用是讓C P U將記憶體值更新為新值,但是有個(gè)條件,記憶體值必須與期望值相同,且C A S操作無(wú)需用戶態(tài)與內(nèi)核態(tài)切換,直接在用戶態(tài)對(duì)記憶體進(jìn)行讀寫操作( 意味著不會(huì)阻塞/線程上下文切換)。

它包含3個(gè)參數(shù)C A S(V,E,N),V表示待更新的記憶體值,E表示預(yù)期值,N表示新值,當(dāng)V值等於E值時(shí),才會(huì)將V值更新成N 值,如果V值和E值不等,不做更新,這就是一次C A S的運(yùn)算。

小白也能與BAT面試官對(duì)線:CAS

簡(jiǎn)單地說(shuō),C A S需要你額外給出一個(gè)期望值,也就是你認(rèn)為這個(gè)變數(shù)現(xiàn)在應(yīng)該是什麼樣子的,如果變數(shù)不是你想像的那樣,說(shuō)明它已經(jīng)被別人修改過(guò)了,你只需要重新讀取,設(shè)定新期望值,再次嘗試修改就好了。

C A S如何保證原子性

原子性是指一個(gè)或多個(gè)運(yùn)算在C P U執(zhí)行的過(guò)程中不被中斷的特性,要麼執(zhí)行,要不執(zhí)行,不能執(zhí)行到一半(不可被中斷的一個(gè)或一系列操作)。

為了保證C A S的原子性,C P U提供了下面兩種方式

  • 匯流排鎖定
  • 快取鎖定

#總線鎖定

匯流排(B U S)是電腦元件間的傳輸資料方式,也就是說(shuō)C P U與其他元件連接傳輸數(shù)據(jù),就是靠總線完成的,例如C P U對(duì)記憶體的讀寫。

小白也能與BAT面試官對(duì)線:CAS

總線鎖定是指C P U使用了匯流排鎖,所謂匯流排鎖定就是使用C P U提供的LOCK#訊號(hào),當(dāng)C P U在總線上輸出LOCK#訊號(hào)時(shí),其他C P U的匯流排請(qǐng)求將會(huì)被阻塞。

小白也能與BAT面試官對(duì)線:CAS

快取鎖定

總線鎖定方式雖然保證了原子性,但是在鎖定期間,會(huì)導(dǎo)致大量阻塞,增加系統(tǒng)的性能開(kāi)銷,所以現(xiàn)代C P U為了提升性能,通過(guò)鎖定範(fàn)圍縮小的思想設(shè)計(jì)出了快取行鎖定(快取行是C P U快取儲(chǔ)存的最小單位)。

所謂快取鎖定是指C P U對(duì)快取行進(jìn)行鎖定,當(dāng)快取行中的共享變數(shù)回寫到記憶體時(shí),其他 C P U會(huì)透過(guò)匯流排嗅探機(jī)制感知該共享變數(shù)是否發(fā)生變化,如果發(fā)生變化,讓自己對(duì)應(yīng)的共享變數(shù)快取行失效,重新從記憶體讀取最新的數(shù)據(jù),快取鎖定是基於快取一致性機(jī)制來(lái)實(shí)現(xiàn)的,因?yàn)榭烊∫恢滦詸C(jī)制會(huì)阻止兩個(gè)以上C P U同時(shí)修改同一個(gè)共享變數(shù)(現(xiàn)代C P U基本上都支援和使用快取鎖定機(jī)制) 。

C A S的問(wèn)題

C A S和鎖定都解決了原子性問(wèn)題,和鎖相比沒(méi)有阻塞、線程上下文你切換、死鎖,所以C A S要比鎖擁有更優(yōu)越的性能,但是C A S同樣有缺點(diǎn)。

C A S的問(wèn)題如下

  • 只能保證一個(gè)共享變數(shù)的原子操作
  • #自旋時(shí)間太長(zhǎng)(建立在自旋鎖的基礎(chǔ)上)
  • ABA問(wèn)題

##只能保證一個(gè)共享變數(shù)原子運(yùn)算

C A S只能針對(duì)一個(gè)共享變數(shù)使用,如果多個(gè)共享變數(shù)就只能使用鎖了,當(dāng)然如果你有辦法把多個(gè)變數(shù)整成一個(gè)變量,利用C A S也不錯(cuò),例如讀寫鎖中state 的高低位。

自旋時(shí)間太長(zhǎng)

#當(dāng)一個(gè)執(zhí)行緒取得鎖定時(shí)失敗,不進(jìn)行阻塞掛起,而是間隔一段時(shí)間再次嘗試獲取,直到成功為止,這種循環(huán)獲取的機(jī)制被稱為自旋鎖(spinlock)。

自旋鎖好處是,持有鎖的線程在短時(shí)間內(nèi)釋放鎖,那些等待競(jìng)爭(zhēng)鎖的線程就不需進(jìn)入阻塞狀態(tài)(無(wú)需線程上下文切換/無(wú)需用戶態(tài)與內(nèi)核態(tài)切換),它們只需要等一等(自旋),等到持有鎖的線程釋放鎖之後即可獲取,這樣就避免了用戶態(tài)和內(nèi)核態(tài)的切換消耗。

自旋鎖壞處顯而易見(jiàn),執(zhí)行緒在長(zhǎng)時(shí)間內(nèi)持有鎖,等待競(jìng)爭(zhēng)鎖的執(zhí)行緒一直自旋,即CPU一直空轉(zhuǎn),資源浪費(fèi)在毫無(wú)意義的地方,所以一般會(huì)限制自旋次數(shù)。

最後來(lái)說(shuō)自旋鎖的實(shí)現(xiàn),實(shí)現(xiàn)自旋鎖定可以基於C A S實(shí)現(xiàn),先定義lockValue物件預(yù)設(shè)值1#, 1代表鎖定資源空閒,0代表鎖定資源被佔(zhàn)用,程式碼如下

public?class?SpinLock?{
????
????//lockValue?默認(rèn)值1
????private?AtomicInteger?lockValue?=?new?AtomicInteger(1);
????
????//自旋獲取鎖
????public?void?lock(){

????????//?循環(huán)檢測(cè)嘗試獲取鎖
????????while?(!tryLock()){
????????????//?空轉(zhuǎn)
????????}

????}
????
????//獲取鎖
????public?boolean?tryLock(){
????????//?期望值1,更新值0,更新成功返回true,更新失敗返回false
????????return?lockValue.compareAndSet(1,0);
????}
????
????//釋放鎖
????public?void?unLock(){
????????if(!lockValue.compareAndSet(1,0)){
????????????throw?new?RuntimeException("釋放鎖失敗");
????????}
????}

}

上面定義了AtomicInteger類型的lockValue變量,AtomicIntegerJava基於C A S實(shí)現(xiàn)的Integer原子操作類,也定義了3個(gè)函數(shù)lock、tryLock、unLock

tryLock函數(shù)-取得鎖定

#
  • 期望值1,更新值0
  • #C A S更新
  • 如果期望值與lockValue值相等,則lockValue值更新為0,傳回true,否則執(zhí)行下面邏輯
  • 如果期望值與lockValue值不相等,不做任何更新,回傳false

unLock函數(shù)-釋放鎖定

  • 期望值0,更新值1
  • C A S更新
  • 如果期望值與lockValue值相等,則lockValue值更新為1,傳回true,否則執(zhí)行下面邏輯
  • #如果期望值與lockValue#值不相等,不做任何更新,返回false

lock函數(shù)-自旋取得鎖定

#
  • 執(zhí)行tryLock函數(shù),傳回true#停止,否則一直循環(huán)
小白也能與BAT面試官對(duì)線:CAS

從上圖可以看出,只有tryLock成功的執(zhí)行緒(lockValue更新為0),才會(huì)執(zhí)行程式碼區(qū)塊,其他執(zhí)行緒個(gè)tryLock自旋等待lockValue被更新成1tryLock成功的線程執(zhí)行unLocklockValue#更新為1),自旋的執(zhí)行緒才會(huì)tryLock成功。

ABA問(wèn)題

C A S需要檢查待更新的記憶體值有沒(méi)有被修改,如果沒(méi)有則更新,但是存在這樣一種情況,如果一個(gè)值原來(lái)是A,變成了B,然後又變成了A,在C A S檢查的時(shí)候會(huì)發(fā)現(xiàn)沒(méi)有被修改。

假設(shè)有兩個(gè)線程,線程1讀取到記憶體值A,線程1時(shí)間片用完,切換到線程2,線程2也讀取到了記憶體值A,並且把它修改為B值,然後再把B值還原到A值,簡(jiǎn)單說(shuō),修改次序是A->B->A,接著執(zhí)行緒1恢復(fù)運(yùn)行,它發(fā)現(xiàn)記憶體值還是A,然後執(zhí)行C A S操作,這就是著名的ABA問(wèn)題,但好像又看不出什麼問(wèn)題。

只是簡(jiǎn)單的資料結(jié)構(gòu),確實(shí)不會(huì)有什麼問(wèn)題,如果是複雜的資料結(jié)構(gòu)可能就會(huì)有問(wèn)題了(使用AtomicReference可以把C A S使用在物件上),以鍊錶資料結(jié)構(gòu)為例,兩個(gè)執(zhí)行緒透過(guò)C A S去刪除頭節(jié)點(diǎn),假設(shè)現(xiàn)在鍊錶有A->B節(jié)點(diǎn)

小白也能與BAT面試官對(duì)線:CAS
  • 線程1刪除A節(jié)點(diǎn),B節(jié)點(diǎn)成為頭節(jié)點(diǎn),正要執(zhí)行C A S(A,A,B)時(shí),時(shí)間片用完,切換到執(zhí)行緒2
  • 執(zhí)行緒2刪除A、B節(jié)點(diǎn)
  • 線程2加入C、A節(jié)點(diǎn),鍊錶節(jié)點(diǎn)變成A- >C
  • 線程1重新取得時(shí)間片,執(zhí)行C A S(A,A,B)
  • 遺失C節(jié)點(diǎn)
  • #

要解決A B A問(wèn)題也非常簡(jiǎn)單,只要追加版本號(hào)即可,每次改變時(shí)加1,即A —> B — > A,變成1A —> 2B —> 3A,在Java#中提供了AtomicStampedRdference可以實(shí)作這個(gè)方案(面試只要問(wèn)了C A S,就一定會(huì)問(wèn)ABA,這塊一定要搞清楚)。

#

以上是小白也能與BAT面試官對(duì)線:CAS的詳細(xì)內(nèi)容。更多資訊請(qǐng)關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

本網(wǎng)站聲明
本文內(nèi)容由網(wǎng)友自願(yuàn)投稿,版權(quán)歸原作者所有。本站不承擔(dān)相應(yīng)的法律責(zé)任。如發(fā)現(xiàn)涉嫌抄襲或侵權(quán)的內(nèi)容,請(qǐng)聯(lián)絡(luò)admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費(fèi)脫衣圖片

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅(qū)動(dòng)的應(yīng)用程序,用於創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費(fèi)的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費(fèi)的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強(qiáng)大的PHP整合開(kāi)發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺(jué)化網(wǎng)頁(yè)開(kāi)發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級(jí)程式碼編輯軟體(SublimeText3)

熱門話題

Laravel 教程
1597
29
PHP教程
1488
72
面試官:Spring Aop 常見(jiàn)註解和執(zhí)行順序 面試官:Spring Aop 常見(jiàn)註解和執(zhí)行順序 Aug 15, 2023 pm 04:32 PM

你一定知道 Spring , 那說(shuō)說(shuō) Aop 的去全部通知順序, Spring Boot 或 Spring Boot 2 對(duì) aop 的執(zhí)行順序影響?說(shuō)說(shuō)你在 AOP 中遇到的那些坑?

某團(tuán)面試:如果線上遇到了OOM,該如何檢查?如何解決?哪些方案? 某團(tuán)面試:如果線上遇到了OOM,該如何檢查?如何解決?哪些方案? Aug 23, 2023 pm 02:34 PM

OOM 意味著程式存在漏洞,可能是程式碼或 JVM 參數(shù)配置引起的。這篇文章跟讀者聊聊,Java 進(jìn)程觸發(fā)了 OOM 後如何排查。

餓了麼筆試題,看似簡(jiǎn)單,難倒一批人 餓了麼筆試題,看似簡(jiǎn)單,難倒一批人 Aug 24, 2023 pm 03:29 PM

在很多公司的筆試題中,千萬(wàn)別小看,都是有坑的,一不小心自己就掉進(jìn)去了。遇到這種關(guān)於循環(huán)的筆試題,建議,自己冷靜思考,一步一步來(lái)。

上週,XX保險(xiǎn)面試,涼了! ! ! 上週,XX保險(xiǎn)面試,涼了! ! ! Aug 25, 2023 pm 03:44 PM

上週,一位群組裡的朋友去平安保險(xiǎn)面試了,結(jié)果有些遺憾,蠻可惜的,但希望你不要?dú)怵H,正如你所說(shuō)的,面試中遇到的問(wèn)題,基本上都是可以通過(guò)背面試題解決的,所以請(qǐng)加油!

5道String面試題,能全答對(duì)的人不到10%! (附答案) 5道String面試題,能全答對(duì)的人不到10%! (附答案) Aug 23, 2023 pm 02:49 PM

這篇來(lái)看看 Java String類別的 5 題面試題,這五題,我自己在面試過(guò)程中親身經(jīng)歷過(guò)幾題目,本篇就帶你了解這些題的答案為什麼是這樣。

小白也能與BAT面試官對(duì)線:CAS 小白也能與BAT面試官對(duì)線:CAS Aug 24, 2023 pm 03:09 PM

Java並發(fā)程式設(shè)計(jì)系列番外篇C A S(Compare and swap),文章風(fēng)格依然是圖文並茂,簡(jiǎn)單易懂,讓讀者們也能與面試官瘋狂對(duì)線。

幾乎所有Java面試都會(huì)問(wèn)到的問(wèn)題:說(shuō)ArrayList和LinkedList的差別 幾乎所有Java面試都會(huì)問(wèn)到的問(wèn)題:說(shuō)ArrayList和LinkedList的差別 Jul 26, 2023 pm 03:11 PM

Java的資料結(jié)構(gòu)是面試考察的重點(diǎn),只要參與Java面試的同學(xué)相信都有所體會(huì)。面試官問(wèn)這類問(wèn)題的時(shí)候往往是想檢視你是否研究過(guò)Java中常用資料類型的底層結(jié)構(gòu),而不是只是簡(jiǎn)單的停留在"會(huì)使用"的層次。

面試官:說(shuō)一下類別載入的過(guò)程(10張圖解) 面試官:說(shuō)一下類別載入的過(guò)程(10張圖解) Aug 23, 2023 pm 03:05 PM

當(dāng)我們要使用一個(gè)類別的時(shí)候,要透過(guò)ClassLoader將類別載入到記憶體中。

See all articles