package countDownLatch; import java.util.ArrayList; import java.util.List; import java.util.concurrent.CountDownLatch; /** * CountDownLatch類是一個同步計數器,構造時傳入int參數,該參數就是計數器的初始值, * 每調用一次countDown()方法,計數器減1,計數器大於0 時, * await()方法會阻塞程序繼續執行 * */ public class CountDownLatchTest { //啓動多個線程,多線程彙總二維數組每行的結果,而後彙總全部結果 private int[][] data = new int[][] { { 1, 3, 5, 7, 9 }, { 2, 4, 6, 8, 10 } }; private CountDownLatch countLatch; public CountDownLatchTest() throws InterruptedException{ //彙總數 int total = 0; List<MyCaculate> threadList = new ArrayList<MyCaculate>(); // 啓動二維數組行數個線程 int threadCount = data.length; countLatch = new CountDownLatch(threadCount); for(int i=0;i<threadCount;i++){ MyCaculate caculate = new MyCaculate(data[i],countLatch); caculate.setName("caculate-thread-"+i); caculate.start(); //System.out.println(caculate.isDone()); threadList.add(caculate); } //阻塞全部線程計算完成 countLatch.await(); // for(MyCaculate c:threadList){ /*while(true){ if(c.isDone()){ total+=c.getSum(); break; } }*/ //由於上面await會阻塞到全部線程完成,因此,不用判斷isDone total+=c.getSum(); } System.out.println("--------------------------------------"); System.out.println("各行彙總結果操做完成,彙總結果:"+total); } public static void main(String[] args) throws InterruptedException { // TODO Auto-generated method stub CountDownLatchTest c = new CountDownLatchTest(); } } class MyCaculate extends Thread { private CountDownLatch countLatch; private int[] row; private int sum; private boolean isDone = false; public MyCaculate(int[] row,CountDownLatch countLatch){ this.row = row; this.countLatch = countLatch; } @Override public void run() { try { System.out.println(Thread.currentThread().getName()+" 開始計算"); for(int i:row){ sum+=i; } }finally{ //作完,計數器減1 countLatch.countDown(); } isDone = true; } public int getSum(){ return sum; } public boolean isDone(){ return isDone; } }
能夠比較一下和CyclicBarrier的區別,Barrier是阻塞的地方,在每一個具體的線程,而CountDownLatch,阻塞在節點上。搞得CountDownLatch反而有點關卡的意思。
java