多線程之CountDownLatch工具類

bbw3 9年前發布 | 1K 次閱讀 Java

CountDownLatch 是一個通用同步工具,它有很多用途。將計數 1 初始化的 CountDownLatch 用作一個簡單的開/關鎖存器,或入口:在通過調用countDown() 的線程打開入口前,所有調用 await 的線程都一直在入口處等待。用 N 初始化的 CountDownLatch 可以使一個線程在N 個線程完成某項操作之前一直等待,或者使其在某項操作完成 N 次之前一直等待。

CountDownLatch 的一個有用特性是,它不要求調用 countDown 方法的線程等到計數到達零時才繼續,而在所有線程都能通過之前,它只是阻止任何線程繼續通過一個await。  

使用場景:

可以實現一個人(也可以是多個人)等待其他所有人來通知他,也可以實現一個人通知多個人。

類似裁判一聲口令,所有運動員開始跑步,所有運動員到達終點后需要裁判員報告成績,裁判員公布結果。

實現如下:

package andy.thread.test;  

import java.util.concurrent.CountDownLatch;  
import java.util.concurrent.ExecutorService;  
import java.util.concurrent.Executors;  

/** 
 * @author Zhang,Tianyou 
 * @version 2014年11月9日 下午2:34:34 
 */  

public class CountdownLatchTest {  

    public static void main(String[] args) {  
        ExecutorService service = Executors.newCachedThreadPool();  
        final CountDownLatch cdOrder = new CountDownLatch(1);  
        final CountDownLatch cdAnswer = new CountDownLatch(3);  
        for (int i = 0; i < 3; i++) {  
            Runnable runnable = new Runnable() {  
                public void run() {  
                    try {  
                        System.out.println("線程"  
                                + Thread.currentThread().getName() + "正準備接受命令");  
                        cdOrder.await();  
                        System.out.println("線程"  
                                + Thread.currentThread().getName() + "已接受命令");  
                        Thread.sleep((long) (Math.random() * 10000));  
                        System.out  
                                .println("線程"  
                                        + Thread.currentThread().getName()  
                                        + "回應命令處理結果");  
                        cdAnswer.countDown();  
                    } catch (Exception e) {  
                        e.printStackTrace();  
                    }  
                }  
            };  
            service.execute(runnable);  
        }  
        try {  
            Thread.sleep((long) (Math.random() * 10000));  

            System.out.println("線程" + Thread.currentThread().getName()  
                    + "即將發布命令");  
            cdOrder.countDown();  
            System.out.println("線程" + Thread.currentThread().getName()  
                    + "已發送命令,正在等待結果");  
            cdAnswer.await();  
            System.out.println("線程" + Thread.currentThread().getName()  
                    + "已收到所有響應結果");  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
        service.shutdown();  

    }  

}  

運行結果如下:

線程pool-1-thread-2正準備接受命令
線程pool-1-thread-1正準備接受命令
線程pool-1-thread-3正準備接受命令
線程main即將發布命令
線程main已發送命令,正在等待結果
線程pool-1-thread-3已接受命令
線程pool-1-thread-2已接受命令
線程pool-1-thread-1已接受命令
線程pool-1-thread-1回應命令處理結果
線程pool-1-thread-2回應命令處理結果
線程pool-1-thread-3回應命令處理結果
線程main已收到所有響應結果

 本文由用戶 bbw3 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!