atomic java_Java中Atomic类的使用分析
1:為什么會(huì)出現(xiàn)Atomic類
在多線程或者并發(fā)環(huán)境中,我們常常會(huì)遇到這種情況 int i=0; i++ 稍有經(jīng)驗(yàn)的同學(xué)都知道這種寫法是線程不安全的。為了達(dá)到線程安全的目的,我們通常會(huì)用synchronized來修飾對(duì)應(yīng)的代碼塊。現(xiàn)在我們有了新的方法,就是使用J.U.C包下的atomic類。
2:Atomic類的原理是什么呢
一句話來說,atomic類是通過自旋CAS操作volatile變量實(shí)現(xiàn)的。
CAS是compare and swap的縮寫,即比較后(比較內(nèi)存中的舊值與預(yù)期值)交換(將舊值替換成預(yù)期值)。它是sun.misc包下Unsafe類提供的功能,需要底層硬件指令集的支撐。
使用volatile變量是為了多個(gè)線程間變量的值能及時(shí)同步。
3:為什么使用Atomic類
按理來說,使用synchroized已經(jīng)能滿足功能需求了。為什么還會(huì)有這個(gè)類呢?那肯定是性能的問題了。
在JDK1.6之前,synchroized是重量級(jí)鎖,即操作被鎖的變量前就對(duì)對(duì)象加鎖,不管此對(duì)象會(huì)不會(huì)產(chǎn)生資源競(jìng)爭(zhēng)。這屬于悲觀鎖的一種實(shí)現(xiàn)方式。
而CAS會(huì)比較內(nèi)存中對(duì)象和當(dāng)前對(duì)象的值是否相同,相同的話才會(huì)更新內(nèi)存中的值,不同的話便會(huì)返回失敗。這是樂觀鎖的一中實(shí)現(xiàn)方式。這種方式就避免了直接使用內(nèi)核狀態(tài)的重量級(jí)鎖。
但是在JDK1.6以后,synchronized進(jìn)行了優(yōu)化,引入了偏向鎖,輕量級(jí)鎖,其中也采用了CAS這種思想,效率有了很大的提升。
4:Atomic類的缺點(diǎn)
ABA問題:
對(duì)于一個(gè)舊的變量值A(chǔ),線程2將A的值改成B又改成可A,此時(shí)線程1通過CAS看到A并沒有變化,但實(shí)際A已經(jīng)發(fā)生了變化,這就是ABA問題。解決這個(gè)問題的方法很簡(jiǎn)單,記錄一下變量的版本就可以了,在變量的值發(fā)生變化時(shí)對(duì)應(yīng)的版本也做出相應(yīng)的變化,然后CAS操作時(shí)比較一下版本就知道變量有沒有發(fā)生變化。atomic包下AtomicStampedReference類實(shí)現(xiàn)了這種思路。Mysql中Innodb的多版本并發(fā)鎖也是這個(gè)原理。
自旋問題:
atomic類會(huì)多次嘗試CAS操作直至成功或失敗,這個(gè)過程叫做自旋。通過自旋的過程我們可以看出自旋操作不會(huì)將線程掛起,從而避免了內(nèi)核線程切換,但是自旋的過程也可以看做CPU死循環(huán),會(huì)一直占用CPU資源。這種情形在單CPU的機(jī)器上是不能容忍的,因此自旋一般都會(huì)有個(gè)次數(shù)限制,即超過這個(gè)次數(shù)后線程就會(huì)放棄時(shí)間片,等待下次機(jī)會(huì)。因此自旋操作在資源競(jìng)爭(zhēng)不激烈的情況下確實(shí)能提高效率,但是在資源競(jìng)爭(zhēng)特別激烈的場(chǎng)景中,CAS操作會(huì)的失敗率就會(huì)大大提高,這時(shí)使用中重量級(jí)鎖的效率可能會(huì)更高。當(dāng)前,也可以使用LongAdder類來替換,它則采用了分段鎖的思想來解決并發(fā)競(jìng)爭(zhēng)的問題。
總結(jié)
以上是生活随笔為你收集整理的atomic java_Java中Atomic类的使用分析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 爬取某在线恶意软件仓库病毒文件进行分析
- 下一篇: APE转MP3的转换码率说明