美文网首页
CountDownLatch(计数器)

CountDownLatch(计数器)

作者: 程序员大黑鱼 | 来源:发表于2020-07-19 22:35 被阅读0次

    CountDownLatch

    概念

    countDownLatch这个类使一个线程等待其他线程各自执行完毕后再执行。

    是通过一个计数器来实现的,计数器的初始值是线程的数量。每当一个线程执行完毕后,计数器的值就-1,当计数器的值为0时,表示所有线程都执行完毕,然后在闭锁上等待的线程就可以恢复工作了。

    核心方法

    //构造方法,初始化一个CountDownLatch实例,指定计数count,一般指定为多线程的数量
    public CountDownLatch(int count);
    //阻塞线程,等待所有线程执行完成释放,继续执行后续代码
    public void await() throws InterruptedException;
    //阻塞线程,指定阻塞时间,阻塞时间超过后,无论所有线程是否执行完毕,都将继续执行后续代码
    public boolean await(long timeout, TimeUnit unit) throws InterruptedException;
    //计数器减1
    public void countDown();
    //获取当前计数器的值
    public long getCount();
    

    示例

    不指定阻塞时间

    import lombok.extern.slf4j.Slf4j;
    import java.util.concurrent.CountDownLatch;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    /**
     * @author scottxuan
     */
    @Slf4j
    public class CountDownLatchExample1 {
    
        private final static int threadCount = 20;
    
        public static void main(String[] args) throws InterruptedException {
            //初始化计数器,一般和线程数目相同
            CountDownLatch countDownLatch = new CountDownLatch(threadCount);
            ExecutorService executor = Executors.newCachedThreadPool();
            for (int i = 0; i < threadCount; i++) {
                final int num = i;
                executor.execute(()->{
                    count(num);
                    //多线程每执行一次,计数器减1
                    countDownLatch.countDown();
                });
            }
            //主线程阻塞,等待所有线程执行完毕,才会执行后续的代码
            countDownLatch.await();
            log.info("all thread finish");
            executor.shutdown();
        }
    
        private static void count(int num){
            log.info("current num {}",num);
        }
    }
    
    //执行结果,所有线程执行完毕后,日志输出  all thread finish
    //22:17:56.095 [pool-1-thread-1] INFO com.aqs.CountDownLatchExample1 - current num 0
    //22:17:56.095 [pool-1-thread-9] INFO com.aqs.CountDownLatchExample1 - current num 8
    //22:17:56.096 [pool-1-thread-7] INFO com.aqs.CountDownLatchExample1 - current num 6
    //22:17:56.095 [pool-1-thread-4] INFO com.aqs.CountDownLatchExample1 - current num 3
    //22:17:56.095 [pool-1-thread-10] INFO com.aqs.CountDownLatchExample1 - current num 9
    //22:17:56.095 [pool-1-thread-8] INFO com.aqs.CountDownLatchExample1 - current num 7
    //22:17:56.095 [pool-1-thread-2] INFO com.aqs.CountDownLatchExample1 - current num 1
    //22:17:56.095 [pool-1-thread-3] INFO com.aqs.CountDownLatchExample1 - current num 2
    //22:17:56.095 [pool-1-thread-6] INFO com.aqs.CountDownLatchExample1 - current num 5
    //22:17:56.095 [pool-1-thread-5] INFO com.aqs.CountDownLatchExample1 - current num 4
    //22:17:56.100 [main] INFO com.aqs.CountDownLatchExample1 - all thread finish
    

    指定阻塞时间

    import lombok.extern.slf4j.Slf4j;
    import java.util.concurrent.CountDownLatch;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.TimeUnit;
    
    /**
     * @author scottxuan
     */
    @Slf4j
    public class CountDownLatchExample2 {
    
        private final static int threadCount = 10;
    
        public static void main(String[] args) throws InterruptedException {
            //初始化计数器,一般和线程数目相同
            CountDownLatch countDownLatch = new CountDownLatch(threadCount);
            ExecutorService executor = Executors.newCachedThreadPool();
            for (int i = 0; i < threadCount; i++) {
                final int num = i;
                executor.execute(()->{
                    count(num);
                    //多线程每执行一次,计数器减1
                    countDownLatch.countDown();
                });
            }
            //主线程阻塞指定的时间,改时间超过后继续执行后续的代码,无论所有线程是否执行完毕
            countDownLatch.await(1000, TimeUnit.MILLISECONDS);
            log.info("await time out");
            executor.shutdown();
        }
    
        private static void count(int num){
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            log.info("current num {}",num);
        }
    }
    
    //输出结果 线程的执行每个需要2000ms,但1000ms之后阻塞释放,先输出
    //22:24:10.016 [main] INFO com.aqs.CountDownLatchExample1 - await time out
    //22:24:11.014 [pool-1-thread-10] INFO com.aqs.CountDownLatchExample1 - current num 9
    //22:24:11.014 [pool-1-thread-2] INFO com.aqs.CountDownLatchExample1 - current num 1
    //22:24:11.015 [pool-1-thread-4] INFO com.aqs.CountDownLatchExample1 - current num 3
    //22:24:11.014 [pool-1-thread-9] INFO com.aqs.CountDownLatchExample1 - current num 8
    //22:24:11.014 [pool-1-thread-1] INFO com.aqs.CountDownLatchExample1 - current num 0
    //22:24:11.015 [pool-1-thread-3] INFO com.aqs.CountDownLatchExample1 - current num 2
    //22:24:11.015 [pool-1-thread-8] INFO com.aqs.CountDownLatchExample1 - current num 7
    //22:24:11.014 [pool-1-thread-6] INFO com.aqs.CountDownLatchExample1 - current num 5
    //22:24:11.015 [pool-1-thread-7] INFO com.aqs.CountDownLatchExample1 - current num 6
    //22:24:11.014 [pool-1-thread-5] INFO com.aqs.CountDownLatchExample1 - current num 4
    

    相关文章

      网友评论

          本文标题:CountDownLatch(计数器)

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