【同步工具】CountDownLatch

本文详细介绍了Java并发包中的CountDownLatch同步工具,包括其初始化计数、减少计数和等待计数归零的机制,以及在实际场景中的使用示例,如线程池协作和等待远程调用完成。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【悲观锁】Java 线程八锁

【线程】Java线程状态的转换

【悲观锁】Synchronized和ReentrantLock的区别

【线程方法】多线程下 wait、notify、park、unpark 和 await、signal 的区别

【内存】Java中的volatile

【设计模式-单例模式】Java 单例模式双重校验锁变量

【CAS-乐观锁】AtomicInteger

【乐观锁】AtomicReference

【设计模式-享元模式】Java 享元模式自定义连接池

【线程池】自定义线程池

【线程池】ThreadPoolExecutor 线程池

【线程池】Executeror 构建线程池的方法

【线程池】ThreadPoolExecutor 的拒绝策略

【悲观锁】主要的 AQS 方法

【悲观锁】ReentrantReadWriteLock

【同步工具】StampedLock

【同步工具】CountDownLatch

【同步工具】CyclicBarrier和CountDownLatch的区别

线程安全集合类

LinkedBlockingQueue 怎么实现的线程安全

CountDownLatch(倒计时)是Java并发包(java.util.concurrent)中的一个同步工具,用于控制一个或多个线程等待其他线程完成操作后再执行。它是一种多线程协作的机制,允许一个或多个线程等待其他线程的信号。

主要特点:

  1. 初始化计数器: 在创建CountDownLatch时,需要指定一个初始计数值。这个计数值表示需要等待完成的线程数量

  2. 减少计数: 每当一个线程完成了需要等待的操作,都会调用countDown()方法来减少计数器的值。

  3. 等待计数归零: 其他线程可以通过调用await()方法来等待计数器归零。如果计数器为零,该方法会立即返回;否则,线程会被阻塞,直到计数器变为零。

使用示例:

下面是一个简单的Java代码示例,演示了CountDownLatch的基本用法:

   private static void test4() throws InterruptedException {
        CountDownLatch latch = new CountDownLatch(3);

        new Thread(() -> {
            log.debug("begin...");
            sleep(1);
            latch.countDown();
            log.debug("end...{}", latch.getCount());
        }).start();

        new Thread(() -> {
            log.debug("begin...");
            sleep(2);
            latch.countDown();
            log.debug("end...{}", latch.getCount());
        }).start();

        new Thread(() -> {
            log.debug("begin...");
            sleep(1.5);
            latch.countDown();
            log.debug("end...{}", latch.getCount());
        }).start();

        log.debug("waiting...");
        latch.await();
        log.debug("wait end...");
    }


11:38:52.854 c.TestCountDownLatch [main] - waiting...
11:38:52.854 c.TestCountDownLatch [Thread-1] - begin...
11:38:52.854 c.TestCountDownLatch [Thread-2] - begin...
11:38:52.854 c.TestCountDownLatch [Thread-0] - begin...
11:38:53.865 c.TestCountDownLatch [Thread-0] - end...2
11:38:54.358 c.TestCountDownLatch [Thread-2] - end...1
11:38:54.863 c.TestCountDownLatch [main] - wait end...
11:38:54.863 c.TestCountDownLatch [Thread-1] - end...0

结合线程池演示:

    private static void test5() {
        CountDownLatch latch = new CountDownLatch(3);
        ExecutorService service = Executors.newFixedThreadPool(4);
        service.submit(() -> {
            log.debug("begin...");
            sleep(1);
            latch.countDown();
            log.debug("end...{}", latch.getCount());
        });
        service.submit(() -> {
            log.debug("begin...");
            sleep(1.5);
            latch.countDown();
            log.debug("end...{}", latch.getCount());
        });
        service.submit(() -> {
            log.debug("begin...");
            sleep(2);
            latch.countDown();
            log.debug("end...{}", latch.getCount());
        });
        service.submit(()->{
            try {
                log.debug("waiting...");
                latch.await();
                log.debug("wait end...");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
    }

12:46:54.982 c.TestCountDownLatch [pool-1-thread-4] - waiting...
12:46:54.982 c.TestCountDownLatch [pool-1-thread-2] - begin...
12:46:54.982 c.TestCountDownLatch [pool-1-thread-3] - begin...
12:46:54.982 c.TestCountDownLatch [pool-1-thread-1] - begin...
12:46:55.992 c.TestCountDownLatch [pool-1-thread-1] - end...2
12:46:56.498 c.TestCountDownLatch [pool-1-thread-2] - end...1
12:46:56.988 c.TestCountDownLatch [pool-1-thread-3] - end...0
12:46:56.988 c.TestCountDownLatch [pool-1-thread-4] - wait end...

等待多个远程调用完毕(在这里不演示countDownLatch,使用future接收):

    private static void test3() throws InterruptedException, ExecutionException {
        RestTemplate restTemplate = new RestTemplate();
        log.debug("begin");
        ExecutorService service = Executors.newCachedThreadPool();
        CountDownLatch latch = new CountDownLatch(4);
        Future<Map<String,Object>> f1 = service.submit(() -> {
            Map<String, Object> response = restTemplate.getForObject("http://localhost:8080/order/{1}", Map.class, 1);
            return response;
        });
        Future<Map<String, Object>> f2 = service.submit(() -> {
            Map<String, Object> response1 = restTemplate.getForObject("http://localhost:8080/product/{1}", Map.class, 1);
            return response1;
        });
        Future<Map<String, Object>> f3 = service.submit(() -> {
            Map<String, Object> response1 = restTemplate.getForObject("http://localhost:8080/product/{1}", Map.class, 2);
            return response1;
        });
        Future<Map<String, Object>> f4 = service.submit(() -> {
            Map<String, Object> response3 = restTemplate.getForObject("http://localhost:8080/logistics/{1}", Map.class, 1);
            return response3;
        });

        System.out.println(f1.get());
        System.out.println(f2.get());
        System.out.println(f3.get());
        System.out.println(f4.get());
        log.debug("执行完毕");
        service.shutdown();
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值