Java中的CAS操作
Java中的CAS的含義
CAS即是Compare and Swap ,它是JDK提供的非阻塞原子性操作,它通過(guò)硬件保證了比較一更新操作的原子性。CAS 操作包含三個(gè)操作數(shù)—內(nèi)存位置(V)、預(yù)期原值(A)和新值(B)。如果內(nèi)存位置的值與預(yù)期原值相匹配,那么處理器會(huì)自動(dòng)將該位置值更新為新值。否則,處理器不做任何操作。一個(gè)線程從主內(nèi)存中得到num值,并對(duì)num進(jìn)行操作,寫入值的時(shí)候,線程會(huì)把第一次取到的num值和主內(nèi)存中num值進(jìn)行比較,如果相等,就會(huì)將改變后的num寫入主內(nèi)存,如果不相等,則一直循環(huán)對(duì)比,知道成功為止。
CAS和Synchronized和volatile的對(duì)比:
由于在Java中,鎖在并發(fā)處理中占據(jù)了一席之地,但是使用Synchronized加鎖有一個(gè)不好的地方,就是當(dāng)一個(gè)線程沒(méi)有獲取到鎖時(shí)會(huì)被阻塞掛起,這會(huì)導(dǎo)致線程上下文的切換和重新調(diào)度開銷。此時(shí)java提供了非阻塞的volatile關(guān)鍵字來(lái)解決共享變量的可見性問(wèn)題,在一定的程度上彌補(bǔ)了鎖帶來(lái)的開銷問(wèn)題,但是volatile只能保證共享變量的可見性,不能解決讀改寫等的原子性問(wèn)題,這個(gè)時(shí)候java提供了CAS。
CAS操作的經(jīng)典問(wèn)題
1.ABA問(wèn)題: 例如:假如線程1使用了CAS修改了初始值為A的變量X,那么線程1首先會(huì)去獲取變量X的值A(chǔ),然后使用CAS操作嘗試修改X的值為B,看似CAS操作成功了,但是在多線程情況下,其實(shí)未必,可能線程2在線程1獲取變量X的值后,CAS操作之前,使用了CAS修改了變量X的值為B,然后再次CAS操作修改變量X的值為A。此時(shí)線程1再去執(zhí)行CAS操作時(shí),雖然變量X的值為A,但是已經(jīng)不是最初的那個(gè)A了。這就是ABA問(wèn)題。
2.循環(huán)時(shí)間長(zhǎng)開銷大 ,持續(xù)占用cpu資源的問(wèn)題: 雖然看似CAS把一些操作變成了一條CPU指令就能完成的原子操作,但是由于它是基于自旋鎖(純用戶態(tài)環(huán)境)實(shí)現(xiàn)的,當(dāng)一個(gè)線程再獲取鎖時(shí),如果發(fā)現(xiàn)鎖被其他線程占有,它并不會(huì)馬上阻塞自己,而是不放棄CPU使用權(quán)的情況下,多次嘗試獲取鎖。這就會(huì)導(dǎo)致CPU資源被長(zhǎng)時(shí)間的占有。
3.只能保證一個(gè)變量的原子性操作的問(wèn)題: 多個(gè)變量的原子操作我們用synchronized加鎖,如果針對(duì)一個(gè)變量我們可以使用CAS減小加鎖的開銷和線程阻塞等待以及重新調(diào)度的開銷。
CAS的應(yīng)用場(chǎng)合
1.線程數(shù)較少,等待時(shí)間短可以采用自旋鎖進(jìn)行CAS嘗試獲取鎖,這樣比Synchronized高效。
2.線程數(shù)較大,等待時(shí)間長(zhǎng),不建議使用自旋鎖,占用CPU較高。
總結(jié)
以上是生活随笔為你收集整理的Java中的CAS操作的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 【小程序项目开发-- 京东商城】uni-
- 下一篇: 富士S2520网络一体机扫描功能异常处理