天天看点

java并发编程之CountDownLatch原理分析与实例

  CountDownLatch的原理与Semaphore是类似的,其内部是用一个计数器控制线程间的同步,也是通过一个AbstractQueuedSynchronizer中state来实现的,state是一个private volatile long类型的对象。CountDownLatch使用state来计数,CountDownLatch的getCount最终调用的是AbstractQueuedSynchronizer的getState(),返回state进行计数。

  应用场景与Semaphore是有区别的:

- Semaphore用于多个共享资源的互斥使用,以及用于并发线程数的控制。

- CountDownLatch是用于调用线程主动等待一个或多个事件的发生,然后再往下执行。并不能用于并发资源的控制

  CountDownLatch在创建时需要指定线程要等待的事件数量,线程需要等待时调用await方法使线程阻塞,在线程继续执行之前必须发生指定数量的事件,调用一次countDown方法就是发生一次事件,state会减1,当state为0时,阻塞的线程被唤醒。下面通过一个实例来看下CountDownLatch应用。

/**
 * 主线程要等待线程TaskThread把count累加到9才继续执行,也就是某个事件发生10,或发生10事件,即要调用10次countDown方法
 * TaskThread每次count加1,调用一次countDown方法,代表事件发生一次,在实际工程中当完成某个事件完成时才执行countDown方法
 * CountDownLatch cdl = new CountDownLatch(10);
 */
public class CountDownLatchDemo {

    public static void main(String args[]) {

        CountDownLatch countDownLatch = new CountDownLatch();

        //创建线程TaskThread并启动,该线程执行10次countDownLatch.countDown()方法
        //然后主线程再继续执行
        new Thread(new Runnable() {
            @Override
            public void run() {
                for(int i = ; i<; i++) {
                    countDownLatch.countDown(); // decrement count
                    System.out.println("事件发生"+(i+)+"次");
                }
            }
        },"TaskThread").start();

        System.out.println("主线程要等待事件发生,才能继续执行");
        try {
            countDownLatch.await();//主线程阻塞等待直到countDownLatch中的计数器减为0
        } catch (InterruptedException exc) {
            System.out.println(exc);
        }

        System.out.println("主线程继续执行");
    }
}