控制線程間的執(zhí)行順序
CyclicBarrier類
- 讓一組線程等待至某種狀態(tài)后全部執(zhí)行
關(guān)于CyclicBarrier可以參考這篇文章同步屏障CyclicBarrier
Thread.join()方法
控制線程間的同步執(zhí)行,將交替執(zhí)行的線程變成順序執(zhí)行的,在B線程前調(diào)用A線程的join函數(shù)入愧,意為在A執(zhí)行完后執(zhí)行B線程
方法:
- t.join():調(diào)用線程t在此之前執(zhí)行完成
- t.join(millseconds):等待t線程執(zhí)行,等待時(shí)間為millseconds毫秒
CountDownLatch類
計(jì)數(shù)器的功能招驴,例如在A線程執(zhí)行前需要執(zhí)行4個(gè)線程,可利用此計(jì)數(shù)器在4個(gè)線程執(zhí)行完成后再執(zhí)行A線程
java內(nèi)存模型
從抽象的角度看枷畏,JMM定義了線程和主內(nèi)存之間的抽象關(guān)系:線程之間的共享變量存儲在主內(nèi)存别厘,每個(gè)線程都有私有的本地內(nèi)存,本地內(nèi)存中存儲了共享變量的副本
線程之間的通信方式
- 共享內(nèi)存
- void notify() 喚醒在此對象監(jiān)視器上等待的單個(gè)線程矿辽。
void notifyAll() 喚醒在此對象監(jiān)視器上等待的所有線程丹允。
void wait() 導(dǎo)致當(dāng)前的線程等待,直到其他線程調(diào)用此對象的notify()方法或notifyAll()方法袋倔。
void wait(long timeout) 導(dǎo)致當(dāng)前的線程等待雕蔽,直到其他線程調(diào)用此對象的notify()方法或notifyAll()方法,或者超過指定的時(shí)間量宾娜。
void wait(long timeout, int nanos) 導(dǎo)致當(dāng)前的線程等待批狐,直到其他線程調(diào)用此對象的notify()方法或notifyAll()方法,或者其他某個(gè)線程中斷當(dāng)前線程前塔,或者已超過某個(gè)實(shí)際時(shí)間量嚣艇。
Volatile+緩存一致性解釋
當(dāng)一個(gè)變量被volatile修飾時(shí):
- 當(dāng)某個(gè)線程對該變量進(jìn)行修改之后,就立即將修改后的值刷回主存华弓,保證主存中永遠(yuǎn)都是最新的值
- volatile對該變量施加了緩存一致性協(xié)議食零,也就是說當(dāng)前線程對該變量進(jìn)行修改后,系統(tǒng)會通知其他線程它們工作緩存中的數(shù)據(jù)已經(jīng)失效寂屏。當(dāng)其他線程再次讀取該變量時(shí)贰谣,就會從主存中讀取該變量然后復(fù)制一份到自己的工作緩存中
- volatile保證了可見性但是不保證原子性
CAS操作
CAS有三個(gè)操作數(shù),內(nèi)存值V迁霎,舊的預(yù)期值A(chǔ)吱抚,要更改的新值B,當(dāng)且僅當(dāng)舊的預(yù)期值A(chǔ)和內(nèi)存值V相同時(shí)考廉,將內(nèi)存值V修改為B秘豹,否則什么都不做
CAS的問題:
- ABA問題:ABA問題是指在CAS操作的時(shí)候,其他線程將變量的值A(chǔ)改成了B之后又改回了A昌粤,本線程使用期望值A(chǔ)與當(dāng)前變量進(jìn)行比較的時(shí)候發(fā)現(xiàn)變量沒有變既绕,實(shí)際上該值已經(jīng)被其他線程改變了啄刹。
解決方法:每次變量更新的時(shí)候,把變量的版本號加一岸更,從而能夠解決ABA問題 - 循環(huán)時(shí)間長開銷大:自旋CAS如果長時(shí)間不成功鸵膏,將給CPU帶來非常大的開銷
- 只能保證一個(gè)共享變量的原子操作