美文网首页
同步工具类之CountDownLatch

同步工具类之CountDownLatch

作者: evil_ice | 来源:发表于2017-01-09 19:41 被阅读15次
一,CountDownLatch概述

CountDownLatch是一种灵活的闭锁实现.闭锁是一种同步工具类,可以延迟线程的进度直到其到达终止状态.闭锁的作用相当于一扇门----在闭锁到达结束状态之前,这扇门一直是关闭的,并没有任何线程能通过,当到达结束状态时,这扇门会打开并允许所有的线程通过.当闭锁达到结束状态后,将不会再改变状态因此这扇门将永远保持打开状态.

二,CountDownLatch使用场景
  • CountDownLatch 是一个通用同步工具,它有很多用途。将计数 1 初始化的 CountDownLatch 用作一个简单的开/关锁存器,或入口:在通过调用 countDown() 的线程打开入口前,所有调用 await 的线程都一直在入口处等待。
public class Test {
    
    public static void main(String[] args){
        Test test = new Test();
        try {
            test.timeTasks(10, new Runnable(){
                @Override
                public void run() {
                    System.out.println("abcd");
                }
                
            });
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
    }
    
    public long timeTasks(int nThreads, final Runnable task) throws InterruptedException{
        final CountDownLatch startGate = new CountDownLatch(1);
        final CountDownLatch endGate = new CountDownLatch(nThreads);
        for(int i=0; i<nThreads; i++){
            Thread t = new Thread(){
                @Override
                public void run() {
                    super.run();
                    try{
                        startGate.await();
                        try{
                            task.run();
                        }finally{
                            endGate.countDown();
                        }
                    }catch(Exception e){
                        
                    }
                }
            };
            t.start();
        }
        long start = System.nanoTime();
        startGate.countDown();
        endGate.await();
        long end = System.nanoTime();
        return end - start;
    }
}
  • 另一种典型用法是,将一个问题分成 N 个部分,用执行每个部分并让锁存器倒计数的 Runnable 来描述每个部分,然后将所有 Runnable 加入到 Executor 队列。当所有的子部分完成后,协调线程就能够通过 await。
    用 N 初始化的 CountDownLatch 可以使一个线程在 N 个线程完成某项操作之前一直等待,或者使其在某项操作完成 N 次之前一直等待。
public class Test {
    private static final int N = 10;

    public static void main(String[] args) {
        CountDownLatch doneSignal = new CountDownLatch(N);
        Executor executor = Executors.newCachedThreadPool();
        for (int i = 0; i < N; ++i) {
            executor.execute(new WorkerRunnable(doneSignal, i));
        }
        try {
            doneSignal.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally{
            System.out.println(Thread.currentThread().getName()+"  "+"前面的N个任务执行完毕了");
        }
    }
}

class WorkerRunnable implements Runnable {
    private final CountDownLatch doneSignal;
    private final int i;

    WorkerRunnable(CountDownLatch doneSignal, int i) {
        this.doneSignal = doneSignal;
        this.i = i;
    }

    public void run() {
        doWork(i);
        doneSignal.countDown();
    }

    void doWork(int i) {
        System.out.println(Thread.currentThread().getName() + " i=" + i);
    }
}

参考
1,<<java并发编程实战>>
2,jdk文档

相关文章

网友评论

      本文标题:同步工具类之CountDownLatch

      本文链接:https://www.haomeiwen.com/subject/hcphbttx.html