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