CountDownLatch 理解

本文介绍了并发编程中Latch机制的基本概念及其应用场景,如资源初始化、依赖服务启动等,并通过CountDownLatch的具体实现,演示了如何使用它来同步多个线程的执行,确保所有任务统一开始与结束。

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

Latch 在英文中是门阀的意思。也就是控制门的开关的关键。
所以,Latch在并发中,就是控制线程访问的。《JCP》中列举了几点用途:
1,等待资源初始化。
2,等待依赖服务启动。
3,等待队友加入活动。

具体的Latch有 CountDownLatch,如果只是说功能什么的,还是比较疑惑。
CountDownLatch 的功能就是初始化一个值,每次调用countDown方法时这个值就减 [b]1[/b]。
注意初始化的值应该是正的,否則Throws:
IllegalArgumentException - if count is negative),而 await方法就是阻塞线程,直到这个值减为[b]0[/b]
这个有什么用呢?

书上给出的例子很好,就是计算多个线程运行消耗的时间。这里我们要注意,如何判断开始和结束呢? 因为多线程中,很可能有的线程启动快,你得选取一个计时点。如果从添加任务开始,那么明显不准缺,添加本身的时间也算上了,所以必须有个时间点,在此之前所有线程都必须等待。于是CountDownLatch变成了发令枪,一声枪响,所有线程就可以狂奔了。
同样结束也是要等待最后一个线程完成。所以也可以用CountDownLatch作为计数员。
这下,我把这个例子变成跑步比赛了。书中的例子好比记录比赛的时间。
运动员就是任务,跑步就是他们的任务,每条跑道就是一个线程。第一个阀门就是发令枪,
在此之前运动员都只是在跑道上等着。第二个阀门则是控制裁判员的,必须等到最后一个运动员跑完才计时结束。
接下来直接看代码:

import java.util.concurrent.CountDownLatch;

public class CompetitionTime {
public long getCompetitionTime( int nAthlete, final Runnable Athlete )
throws InterruptedException {
// the starting gun just shot once.
final CountDownLatch startingGun = new CountDownLatch( 1 );
// every athlete should complete the competition.
final CountDownLatch endCompetition = new CountDownLatch( nAthlete );

for ( int i = 0; i < nAthlete; i++ ) {
Thread t = new Thread() {
public void run() {
try {
//before running, athlete must wait for shot of the starting gun
startingGun.await();
try {
Athlete.run();
}
finally {
//when he finishes his competition,let the referee know
endCompetition.countDown();
}
}
catch ( InterruptedException ignored ) {

}
}
} ;
t.start();
//now the thread must wait for the shot of the starting gun
}

//the following two can exchange the order.
long start = System.nanoTime();
startingGun.countDown();
//then we just wait for the last athlete done.
// the main thread is blocking.
endCompetition.await();
// that means all athlete finish their competition.
long end = System.nanoTime();
return end - start;
}
}
CountDownLatchJava中一个非常有用的同步工具类,它可以让一个或多个线程等待其他线程完成它们的操作后再执行。在Java中,CountDownLatch类是通过一个计数器来实现的,计数器的初始值可以设置为任何整数。当某个线程调用CountDownLatch的await()方法时,它会阻塞等待计数器的值变为0;而其他线程执行完它们的操作后会通过调用CountDownLatch的countDown()方法来减少计数器的值。当计数器的值变为0时,await()方法将返回,线程得以继续执行。 下面是一个使用CountDownLatch的示例代码: ```java import java.util.concurrent.CountDownLatch; public class CountDownLatchExample { public static void main(String[] args) throws InterruptedException { int numThreads = 5; CountDownLatch latch = new CountDownLatch(numThreads); for (int i = 0; i < numThreads; i++) { new Thread(new Worker(i, latch)).start(); } latch.await(); System.out.println("All threads have finished!"); } static class Worker implements Runnable { private int id; private CountDownLatch latch; public Worker(int id, CountDownLatch latch) { this.id = id; this.latch = latch; } public void run() { System.out.println("Worker " + id + " is working..."); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Worker " + id + " has finished."); latch.countDown(); } } } ``` 在这个例子中,我们创建了5个线程,并用CountDownLatch来等待它们全部执行完毕。每个线程都会休眠1秒钟,然后调用countDown()方法来减少计数器的值,最终当所有线程都执行完毕时,await()方法返回,打印出"All threads have finished!"。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值