------本文主要記錄CountDownLatch,CyclicBarries、Semaphore工具提供的并發(fā)流程控制手段
等待多線程完成的CountDownLatch
允許一個或多個線程等待其它線程完成操作,首先我會想到之前看過的fork/join框架 中的join 等待某線程執(zhí)行完再返回侦鹏,這個函數(shù)的實(shí)際功能是循環(huán)判斷線程是否存活如果不存活就 wait(0)永遠(yuǎn)的等待下去湾盒。然而jdk5之后對countdownlatch有優(yōu)化為了不讓主線程一直等待,就使用另外一個await(long time,TimeUtil util) 實(shí)則回一個特定時間就返回 而不管線程是否存活痰憎。
static CountDownLarch c = new CountDownLatch(n)
//每執(zhí)行一次countDown方法 n值減1 n為0之后 就從await()返回
同步屏障 CyclicBarrier
讓一組線程到達(dá)一個屏障時被阻塞,直到最后一個線程到達(dá)屏障時攀涵,屏障才會開門铣耘,所以被屏障攔截的線程才會繼續(xù)運(yùn)行。
public class CyclicBarrierTest{
static CyclicBarrier c = new CyclicBarrier(2);
public static void main(String[] args){
new Thread(new Runnable() {
public void run(){
try{
c.await();
}catch(Exception e){
}
system.out.println(1);
}
}).start();
//調(diào)用await()意思是告知CyclicBarrier此線程已
//到達(dá)屏障以故,然后當(dāng)前線程被阻塞直所有線程都到了
try{
c.await();
}catch(Exception e){
}
system.out.println(1);
}
}
輸出可能是 12 也可能是21 因線程調(diào)度由cpu決定兩個線程都可能先執(zhí)行到同步屏障蜗细, 參數(shù)2表示屏障需要等待兩個線程到達(dá)才會開門。
Cyclicbarrier還可以有一個參數(shù)
CyclicBarrier(int parties,Runnable barrierAction);
表示線程到達(dá)屏障時優(yōu)先執(zhí)行barrierAction類的run方法怒详。
CyclicBarrier和CountDownLatch的區(qū)別
CountDownLatch的計(jì)數(shù)器只能有用一次炉媒,而CyclicBarrier計(jì)數(shù)器可以reset(),所以后者更實(shí)用業(yè)務(wù)更加復(fù)雜的場景棘利。
CyclicBarrier還有其他的方法 如getNumberWaiting用來獲取屏障阻塞的線程數(shù)量 isBroken用來了解阻塞的線程是否被中斷橱野,所謂線程阻塞就是被動的在搶占資源中得不到資源,被動的掛起在內(nèi)存善玫,等待某種信號源或信號量將他喚醒(只釋放CPU不釋放內(nèi)存水援。)
控制并發(fā)線程數(shù)的Semaphore
信號量密强,用來控制訪問特定資源的線程數(shù)量,協(xié)調(diào)線程以保證合理的使用公共資源蜗元,
應(yīng)用場景
- 流量控制
Semaphore s = new Semaphore(10)或渤;
//10表示允許10個線程并發(fā)執(zhí)行通過s.aquire()獲取 s.release歸還使用權(quán)。
線程間交換數(shù)據(jù)的Exchanger
用于進(jìn)行線程間的數(shù)據(jù)交換奕扣,它提供一個同步點(diǎn)薪鹦,到達(dá)這個同步點(diǎn)兩個線程就會交換彼此的數(shù)據(jù),只有兩個線程都執(zhí)行了exchange方法惯豆,都到達(dá)同步點(diǎn)時池磁,兩個線程就可以交換數(shù)據(jù)
這個工具可用于遺傳算法,校對工作楷兽。