CountdownLatch
countdownLatch為多個(gè)線程整體到達(dá)條件時(shí)通知await的線程,即時(shí)序圖如下:
由圖中我們知道魏割,執(zhí)行的.countDown()方法的線程不會(huì)阻塞會(huì)接著干自己的事情庭呜,當(dāng)thread1,2,3這3個(gè)線程都已經(jīng)執(zhí)行了countdown的時(shí)候就會(huì)通知 countdownLatch.await()上等待的線程滑进。 其具體表現(xiàn)是一撥人等另一撥人。
具體偽代碼交互模式為:
main(){
CountdownLatch countDownLatch = new CountDownLatch(5); //主線程
//countdown操作
new Thread( new Runnable(){ public void run(){ countDownLatch .countdown() }}).start();
new Thread( new Runnable(){ public void run(){ countDownLatch .countdown() }}).start();
//await操作募谎,等待countdownLatch變成0扶关,才繼續(xù)執(zhí)行
new Thread( new Runnable(){ public void run(){ countDownLatch .await() }}).start();
}
相關(guān)countlatchdown代碼可以參考:https://blog.csdn.net/simonchi/article/details/47150173
CyclicBarrier
由圖我們知道,所有調(diào)用了CyclicBarrier.await()的線程會(huì)被阻塞数冬,知道所有在Cyclic上的線程都await了后會(huì)整體釋放一起恢復(fù)執(zhí)行节槐。其具體表現(xiàn)是等一撥人籌齊了再走。
其交互偽代碼為:
CyclicBarrier cb = new CyclicBarrier(3)
new Thread( new Runnable(){ public void run(){ cb.await() }}).start();
new Thread( new Runnable(){ public void run(){ cb.await()}}).start();
//如果沒(méi)有第三個(gè)線程執(zhí)行cb.await()的話拐纱,那么 第一第二個(gè)線程永遠(yuǎn)在等待(除非被interrupted)
Exchanger
Exchange用于另個(gè)線程之間交換數(shù)據(jù)铜异,如果一個(gè)線程thread1執(zhí)行了Exchanger.exchange()方法另一個(gè)線程thread2還沒(méi)有,那么thread1會(huì)被阻塞戳玫。其交互圖如下:
Exchanger經(jīng)常用于兩個(gè)線程交換隊(duì)列數(shù)據(jù)熙掺。
Final Exchanger<List<Integer>> exchanger = new Exchanger<List<Integer>>();
//兩個(gè)線程交換隊(duì)列
thread1 = new Thread
{
new Runnabler(){
.......
list1 =new Arraylist<String>();
list1 = exchanger.exchanger(list1)
}
}.start()
thread2 = new Thread
{
new Runnabler(){
.......
list2 =new Arraylist<String>();
list2 = exchanger.exchanger(list2)
}
}.start()
Semaphore
信號(hào)量用于控制線程之間的并發(fā),比如5臺(tái)機(jī)器8個(gè)工人操作每臺(tái)機(jī)器只能被一個(gè)工人操作咕宿。那么可以通過(guò)semaphore來(lái)操作币绩。
main(){
Semaphore semaphore = new Semaphore(5);
new Runnable()
{
semaphore.acquire();//如果沒(méi)有獲取到線程阻塞
.......do job....
semaphore.release();
}
}
//注意 semaphore.acquire()沒(méi)有獲取的話阻塞,如果不想阻塞可以替換成semaphore.tryacquire();//如果獲取成功返回true府阀,沒(méi)有獲取成功返回false
wait, notify,notifyAll
查看jdk Object.java 查看了釋義缆镣,七對(duì)wait和notify解釋如下:
wait:cause the current thread to wait until another thread to invoke the notify/notifyall method of this object.
1.首先什么是current thread即當(dāng)前正在執(zhí)行queue.wait()的線程 currentThread1。
2.我們需要通過(guò)另外一個(gè)線程 調(diào)用 queue.notify()來(lái)喚醒在 queue對(duì)象上等待的線程(有個(gè)等待隊(duì)列)试浙。
寫(xiě)代碼需要注意以下幾點(diǎn):
1.wait和notify用于線程間協(xié)同董瞻,它是一個(gè)線程共享對(duì)象,所以需要加鎖或者其他機(jī)制保證線程間可見(jiàn)和同步田巴。
2.在調(diào)用wait的時(shí)候钠糊,要先判斷是否條件不夠。
具體以生產(chǎn)者消費(fèi)者模型:
producer:
synchronized(queue)
{
condition = hold
queue.notifyall();
// 喚醒等待的線程(consumer線程壹哺,告訴他們有工作可以做了)去取隊(duì)列數(shù)據(jù)工作
}
consumer:
synchronized(queue)
{
while (<condition does not hold>) //該consumer下次任務(wù)同樣要判斷
queue.wait(timeout, nanos);
// Perform action appropriate to condition ->這個(gè)是被喚醒之后執(zhí)行的吧抄伍。
}
}
}
疑問(wèn):要consumer線程一直while檢查條件,那么意思是說(shuō)queue.wati()后consumer線程還會(huì)去進(jìn)行下一次循環(huán)遍歷么管宵?