首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Java并发基础:CountDownLatch全面解析!

Java并发基础:CountDownLatch全面解析! - 程序员古德内容概要

CountDownLatch的优点在于能够简洁高效地协调多个线程的执行顺序,确保一组线程都完成后才触发其他线程的执行,适用于资源加载、任务初始化等场景。它提供了清晰的等待/通知机制,易于理解和使用,是提升多线程程序性能和可靠性的重要工具。

核心概念

CountDownLatch允许一个或多个线程等待其他一组线程完成操作,它使用一个计数器来初始化需要等待的线程数量,每当一个线程完成了它的任务,计数器就会递减,当计数器归零时,意味着所有需要等待的线程都已经完成了它们的任务,此时等待的线程(通常是一个或多个主线程)就可以继续执行了。

使用CountDownLatch可以更精确地控制线程的执行顺序和时机,例如,在一个多阶段的任务中,可能希望所有的数据预处理线程都完成后,再启动一个线程来进行数据汇总,使用CountDownLatch 可以很容易地实现这种需求。

代码案例

下面是一个简单的代码示例,演示了如何使用CountDownLatch,如下代码:

import java.util.concurrent.CountDownLatch;

public class CountDownLatchExample {

// 定义一个包含3个计数的CountDownLatch

private static final int WORKER_THREADS = 3;

private static final CountDownLatch latch = new CountDownLatch(WORKER_THREADS);

public static void main(String[] args) throws InterruptedException {

// 创建并启动工作线程

for (int i = 0; i < WORKER_THREADS; i++) {

new Thread(() -> {

System.out.println("工作线程" + Thread.currentThread().getId() + "正在执行任务...");

try {

// 模拟任务执行时间

Thread.sleep((long) (Math.random() * 1000));

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("工作线程" + Thread.currentThread().getId() + "任务执行完毕!");

// 当前工作线程完成任务后,CountDownLatch计数减1

latch.countDown();

}).start();

}

// 主线程在此等待,直到所有工作线程都完成任务

latch.await();

System.out.println("所有工作线程都已完成任务,主线程继续执行...");

}

}

在这段代码中,定义了一个CountDownLatch实例latch,并初始化其计数为工作线程的数量(在这个例子中是3),在main方法中,创建了3个工作线程,并启动它们,每个工作线程都执行一个任务,任务完成后调用latch.countDown()方法将CountDownLatch的计数减1,主线程调用latch.await()方法等待,直到CountDownLatch的计数减为0(即所有工作线程都完成了任务)才会继续执行,当所有工作线程都完成任务后,主线程会打印出一条消息表示它可以继续执行了。

如下代码执行结果:

工作线程11正在执行任务...

工作线程12正在执行任务...

工作线程13正在执行任务...

工作线程12任务执行完毕!

工作线程11任务执行完毕!

工作线程13任务执行完毕!

所有工作线程都已完成任务,主线程继续执行...

核心API

CountDownLatch 类主要提供了以下几个核心方法:

CountDownLatch(int count),构造函数,用来初始化一个倒计时计数器,设置初始计数值,参数 count 表示需要等待的事件数量。

void await(),使当前线程在锁存器倒计数至零之前一直等待,除非线程被中断或发生了其他不可预料的事情,如果当前计数为零,则此方法立即返回,如果当前计数大于零,则为了使线程能够继续执行,当前线程必须禁用中断,并且锁存器计数必须减至零,或者此线程必须被其他线程中断。

boolean await(long timeout, TimeUnit unit),使当前线程在锁存器倒计数至零之前一直等待,除非线程被中断、超出了指定的等待时间,或者发生了其他不可预料的事情,如果当前计数为零,则此方法立即返回 true 值,如果当前计数大于零,则此方法将一直阻塞,直到以下三种情况之一发生:

锁存器计数减至零;此时方法返回 true。

其他线程中断了当前线程;此时方法抛出 InterruptedException。

已超出了指定的等待时间;此时方法返回 false。

void countDown(),递减锁存器的计数,如果计数到达零,则释放所有等待的线程,如果当前计数大于零,则将计数减少,如果新的计数为零,出于线程调度的目的,将释放所有等待的线程。

long getCount(),返回当前计数,此方法通常用于调试和测试,而不是用于同步控制,因为它可能与其他操作竞态。

其中await() 和 countDown() 是最常用的,await() 方法用于阻塞当前线程,直到计数器减至零;countDown() 方法用于将计数器减一,这两个方法通常在不同的线程中调用,以实现线程间的协调。

核心总结

Java并发基础:CountDownLatch全面解析!- 程序员古德

CountDownLatch是Java并发编程中的一把利器,它简洁易用,能有效协调多个线程的执行顺序,优点在于,它能确保一组线程都完成后,再触发其他线程的执行,这在很多场景下都非常有用,比如资源加载、任务初始化等,但同时,它也有一些局限性,比如无法重置计数,一旦计数到零,就不能再次使用了。而且,它只能等待固定数量的线程,不够灵活。

  • 发表于:
  • 原文链接https://page.om.qq.com/page/OHmILcNIlnMeMldS54VdbSBw0
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券