身為JAVA工作者必須了解的實(shí)戰(zhàn)知識(shí)(十四)

一、鎖的劣勢

鎖定后如果未釋放,再次請(qǐng)求鎖時(shí)會(huì)造成阻塞,多線程調(diào)度通常遇到阻塞會(huì)進(jìn)行上下文切換,造成更多的開銷。

在掛起與恢復(fù)線程等過程中存在著很大的開銷,并且通常存在著較長時(shí)間的中斷。

鎖可能導(dǎo)致優(yōu)先級(jí)反轉(zhuǎn),即使較高優(yōu)先級(jí)的線程可以搶先執(zhí)行,但仍然需要等待鎖被釋放,從而導(dǎo)致它的優(yōu)先級(jí)會(huì)降至低優(yōu)先級(jí)線程的級(jí)別。

二、硬件對(duì)并發(fā)的支持

處理器填寫了一些特殊指令,例如:比較并交換、關(guān)聯(lián)加載/條件存儲(chǔ)。

1 比較并交換

CAS的含義是:“我認(rèn)為V的值應(yīng)該為A,如果是,那么將V的值更新為B,否則不需要修改告訴V的值實(shí)際為多少”。CAS是一項(xiàng)樂觀鎖技術(shù)。

模擬CAS操作例子:

[java]view plaincopy

print?

@?ThreadSafe

publicclassSimulatedCAS?{

@?GuardeBy("this")privateintvalue?;

publicsynchronizedintget(){

returnvalue?;

}

publicsynchronizedintcompareAndSwap(intexpectedValue,intnewValue){

intoldValue?=?value?;

if(oldValue?==?expectedValue)

value?=?newValue;

returnoldValue;

}

publicsynchronizedbooleancompareAndSet(intexpectedValue,intnewValue){

return(expectedValue?==?compareAndSwap(expectedValue,?newValue));

}

}

2 非阻塞的計(jì)數(shù)器

基于CAS實(shí)現(xiàn)的非阻塞計(jì)數(shù)器

[java]view plaincopy

print?

@?ThreadSafe

publicclassCasCounter?{

privateSimulatedCAS?value?;

publicintgetValue(){

returnvalue?.get();

}

publicintincrement(){

intv;

do{

v?=?value?.get();

}while(v?!=?value?.compareAndSwap(v,?v?+1));

returnv?+1;

}

}

CAS的主要缺點(diǎn)是:它將使調(diào)度者處理競爭問題(通過重試、回退、放棄),而在使用鎖中能自動(dòng)處理競爭問題(線程在獲得鎖之前將一直阻塞)。

3 JVM對(duì)CAS的支持

[java]view plaincopy

print?

java.util.concurrent.atomic?類的小工具包,支持在單個(gè)變量上解除鎖的線程安全編程。

AtomicBoolean?可以用原子方式更新的boolean值。

AtomicInteger?可以用原子方式更新的int值。

AtomicIntegerArray?可以用原子方式更新其元素的int數(shù)組。

AtomicIntegerFieldUpdater?基于反射的實(shí)用工具,可以對(duì)指定類的指定volatileint字段進(jìn)行原子更新。

AtomicLong?可以用原子方式更新的long值。

AtomicLongArray?可以用原子方式更新其元素的long數(shù)組。

AtomicLongFieldUpdater?基于反射的實(shí)用工具,可以對(duì)指定類的指定volatilelong字段進(jìn)行原子更新。

AtomicMarkableReference?AtomicMarkableReference?維護(hù)帶有標(biāo)記位的對(duì)象引用,可以原子方式對(duì)其進(jìn)行更新。

AtomicReference?可以用原子方式更新的對(duì)象引用。

AtomicReferenceArray?可以用原子方式更新其元素的對(duì)象引用數(shù)組。

AtomicReferenceFieldUpdater?基于反射的實(shí)用工具,可以對(duì)指定類的指定volatile字段進(jìn)行原子更新。

AtomicStampedReference?AtomicStampedReference?維護(hù)帶有整數(shù)“標(biāo)志”的對(duì)象引用,可以用原子方式對(duì)其進(jìn)行更新。

三、原子變量類

1 原子變量是一種“更好的volatile”

通過CAS來維持包含多個(gè)變量的不變性條件例子:

[java]view plaincopy

print?

importjava.util.concurrent.atomic.AtomicReference;

publicclassCasNumberRange?{

privatestaticclassIntPair{

finalintlower?;//?不變性條件:?lower?<=?upper

finalintupper?;

publicIntPair(intlower,intupper)?{

this.lower?=?lower;

this.upper?=?upper;

}

}

privatefinalAtomicReference?values?=

newAtomicReference(newIntPair(0,0));

publicintgetLower(){

returnvalues?.get().?lower;

}

publicintgetUpper(){

returnvalues?.get().?upper;

}

publicvoidsetLower(inti){

while(true){

IntPair?oldv?=?values?.get();

if(i?>?oldv.upper?){

thrownewIllegalArgumentException("Cant't?set?lower?to?"+?i?+"?>?upper");

}

IntPair?newv?=newIntPair(i,?oldv.upper?);

if(values?.compareAndSet(oldv,?newv)){

return;

}

}

}

//?對(duì)setUpper采用類似的方法

}

2 性能比較:鎖與原子變量

使用ReentrantLock、AtomicInteger、ThreadLocal比較,通常情況下效率排序是ThreadLocal >?AtomicInteger >?ReentrantLock。

四、非阻塞算法

1 非阻塞的棧

[java]view plaincopy

print?

importjava.util.concurrent.atomic.AtomicReference;

publicclassConcurrentStack?{

privateAtomicReference>?top?=newAtomicReference>();

publicvoidpush(E?item){

Node?newHead?=newNode(item);

Node?oldHead;

do{

oldHead?=?top?.get();

newHead.?next?=?oldHead;

}while(!top?.compareAndSet(oldHead,?newHead));

}

publicE?pop(){

Node?oldHead;

Node?newHead;

do{

oldHead?=?top?.get();

if(oldHead?==null)?{

returnnull;

}

newHead?=?oldHead.?next?;

}while(!top?.compareAndSet(oldHead,?newHead));

returnoldHead.item?;

}

privatestaticclassNode{

publicfinalE?item;

publicNode?next?;

publicNode(E?item){

this.item?=?item;

}

}

}

2 非阻塞的鏈表

CAS基本使用模式:在更新某個(gè)值時(shí)存在不確定性,以及在更新失敗時(shí)重新嘗試。

[java]view plaincopy

print?

importjava.util.concurrent.atomic.AtomicReference;

@?ThreadSafe

publicclassLinkedQueue?{

privatestaticclassNode{

finalE?item;

finalAtomicReference>?next;

publicNode(E?item,?Node?next){

this.item?=?item;

this.next?=newAtomicReference>(next);

}

}

privatefinalNode?dummy?=newNode(null,null);

privatefinalAtomicReference>?head?=

newAtomicReference>(dummy);

privatefinalAtomicReference>?tail?=

newAtomicReference>(dummy);

publicbooleanput(E?item){

Node?newNode?=newNode(item,null);

while(true){

Node?curTail?=?tail.get();

Node?tailNext?=?curTail.next.get();

if(curTail?==?tail.get()){

if(tailNext?!=null){

//?隊(duì)列處于中間狀態(tài),推進(jìn)尾節(jié)點(diǎn)

tail.compareAndSet(curTail,?tailNext);

}else{

//?處于穩(wěn)定狀態(tài),?嘗試插入新節(jié)點(diǎn)

if(curTail.next.compareAndSet(null,?newNode)){

//?插入操作成功,嘗試推進(jìn)尾節(jié)點(diǎn)

tail.compareAndSet(curTail,?tailNext);

returntrue;

}

}

}

}

}

}

3 原子的域更新器

原子的域更新器類表示有volatile域的一種基于反射的“視圖”,從而能夠在已有的volatile域上使用CAS

[java]view plaincopy

print?

privatestaticclassNode{

privatefinalE?item;

privatevolatileNode?next;

publicNode(E?item){

this.item?=?item;

}

}

privatestaticAtomicReferenceFieldUpdater?nextUpdater

=?AtomicReferenceFieldUpdater.newUpdater(Node.class,?Node.class,"next");

4 ABA問題

處理V的值首先由A變成B,再由B變成A的問題。

好了同學(xué)們,我能介紹的也都全部介紹完給你們了,如果下獲得更多JAVA教學(xué)資源,可以選擇來我們這里共同交流,群:240448376,很多大神在這里切磋學(xué)習(xí),不懂可以直接問,晚上還有大牛免費(fèi)直播教學(xué)。

注:加群要求

1、具有一定工作經(jīng)驗(yàn)的,面對(duì)目前流行的技術(shù)不知從何下手,需要突破技術(shù)瓶頸的可以加,有些應(yīng)屆生和實(shí)習(xí)生也可以加。

2、在公司待久了,過得很安逸,但跳槽時(shí)面試碰壁。需要在短時(shí)間內(nèi)進(jìn)修、跳槽拿高薪的可以加。

3、如果沒有工作經(jīng)驗(yàn),但基礎(chǔ)非常扎實(shí),對(duì)java工作機(jī)制,常用設(shè)計(jì)思想,常用java開發(fā)框架掌握熟練的,可以加。

4、覺得自己很牛B,一般需求都能搞定。但是所學(xué)的知識(shí)點(diǎn)沒有系統(tǒng)化,很難在技術(shù)領(lǐng)域繼續(xù)突破的可以加。

5.阿里Java高級(jí)大牛直播講解知識(shí)點(diǎn),分享知識(shí),多年工作經(jīng)驗(yàn)的梳理和總結(jié),帶著大家全面、科學(xué)地建立自己的技術(shù)體系和技術(shù)認(rèn)知!

PS:現(xiàn)在主要講解的內(nèi)容是(反射原理枚舉原理與應(yīng)用、注解原理、常用設(shè)計(jì)模式、正規(guī)表達(dá)式高級(jí)應(yīng)用、JAVA操作Office原理詳解、JAVA圖像處理技術(shù),等多個(gè)知識(shí)點(diǎn)的詳解和實(shí)戰(zhàn))

6.小號(hào)或者小白之類加群一律不給過,謝謝。

最后,每一位讀到這里的網(wǎng)友,感謝你們能耐心地看完。覺得對(duì)你有幫助可以給個(gè)喜歡!希望在成為一名更優(yōu)秀的Java程序員的道路上,我們可以一起學(xué)習(xí)、一起進(jìn)步

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容