线程同步工具CountDownLatch的使用

CountDownLatch 用法

CountDownLatch是java.util.concurrent包中一个类,CountDownLatch只要提供的机制是多个(具体数量等于初始化CountDownLatch时count的值)线程都达到了预期状态或者完成了预期工作时触发事件,其他线程可以等待这个事件来触发自己后续的工作。等待的线程可以是多个,即CountDownLatch可以唤醒多个等待的线程。到达自己预期状态的线程会调用CountDownLatch的countDown方法,而等待的线程会调用CountDownLatch的await方法。
线程同步工具CountDownLatch的使用

结合以下几个例子,可以快速掌握这个这个类的基本使用方法:
例一:

public static void main(String[] args) throws InterruptedException {
    CountDownLatch countDown = new CountDownLatch(1);
        CountDownLatch await = new CountDownLatch(5);

        // 依次创建并启动处于等待状态的5个MyRunnable线程
        for (int i = 0; i < 5; ++i) {
            new Thread(new MyRunnable(countDown, await)).start();
        }

        System.out.println("用于触发处于等待状态的线程开始工作......");
        System.out.println("用于触发处于等待状态的线程工作完成,等待状态线程开始工作......");
        countDown.countDown();
        await.await();
        System.out.println("Bingo!");
}

public class MyRunnable implements Runnable {

    private final CountDownLatch countDown;
    private final CountDownLatch await;

    public MyRunnable(CountDownLatch countDown, CountDownLatch await) {
        this.countDown = countDown;
        this.await = await;
    }

    public void run() {
        try {
            countDown.await();//等待主线程执行完毕,获得开始执行信号...
            System.out.println("处于等待的线程开始自己预期工作......");
            await.countDown();//完成预期工作,发出完成信号...
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
运行结果:
用于触发处于等待状态的线程开始工作......
用于触发处于等待状态的线程工作完成,等待状态线程开始工作......
处于等待的线程开始自己预期工作......
处于等待的线程开始自己预期工作......
处于等待的线程开始自己预期工作......
处于等待的线程开始自己预期工作......
处于等待的线程开始自己预期工作......
Bingo!
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

例子二:

public class TestDemo2 {

    public static void main(String[] args) throws InterruptedException {
        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(5, 10, 100, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(5));
        int count = 10;
        final CountDownLatch latch = new CountDownLatch(count);

        for (int i = 0; i < count; i++) {
            threadPool.execute(new MyRunnable1(latch, i));
        }

        latch.await();
        System.err.println("等待线程被唤醒!");
        threadPool.shutdown();
    }
}

class MyRunnable1 implements Runnable {

    CountDownLatch latch = null;
    int i;

    public MyRunnable1(CountDownLatch latch, int i) {
        this.latch = latch;
        this.i = i;
    }

    @Override
    public void run() {
        System.err.println("线程" + i +"完成了操作...");
        try {
            Thread.currentThread();
            Thread.sleep(4000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        latch.countDown();
    }

}
运行结果:
线程0完成了操作...
线程3完成了操作...
线程2完成了操作...
线程1完成了操作...
线程4完成了操作...//暂停4秒
线程5完成了操作...
线程6完成了操作...
线程8完成了操作...
线程7完成了操作...
线程9完成了操作...//暂停4秒
等待线程被唤醒!
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52