使用CountDownLatch实现多线程闭锁
CountDownLatch
是一个同步工具类,可以用来协调多个线程的执行时间。
例如:可以让A线程在其他线程运行完毕之后再执行。也就是说,如果其他线程没有执行完毕,则A线程就会一直等待。这种特性也称之为闭锁。
闭锁的使用场景:
-
确保某个计算,在其需要的所有资源都准备就绪后再执行。
-
确保某个服务,在其依赖的所有服务都已启动后再启动。
-
确保某个任务,在所有参与者都准备就绪后再执行。
CountDownLatch的原理
CountDownLatch
在创建时,会指定一个计数器,表示等待的执行线程数量。然后每个线程在执行完毕之后,分别调用一次countDown()
方法,用来递减计数器,表示一个线程数执行完了。此时线程A可以调用await()
方法,使当前线程一直阻塞,直到计数器为0,线程A才会执行。如果线程A一直无法等到计数器为0,则会显示等待超时,也可以在线程A等待时,通过程序中断。
学习CountDownlatch
的代码如下:
package com.geovis.bin.custom.study.wangbin;
import java.util.concurrent.CountDownLatch;
/**
* @Author: Wangb
* @EMail: 1149984363@qq.com
* @Date: 25/12/2021 上午10:32
* @Description
*/
public class TestCountDownLatch {
public static void main(String[] args) {
//计数器为10
CountDownLatch countDownLatch = new CountDownLatch(10);
/**
* 将CountDownLatch对象传递到线程的run()方法中,当每个线程执行完毕run()后就将计数器减1
*/
MyThread myThread = new MyThread(countDownLatch);
long start = System.currentTimeMillis();
//创建10个线程,并执行
for (int i = 0; i < 10; i++) {
new Thread(myThread).start();
}
try {
/**
* 主线程(main)等待:等待的计数器为0;即当CountDownLatch中的计数器为0时,Main线程才会继续执行。
*/
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
long end = System.currentTimeMillis();
System.out.println("耗时:" + (end - start));
}
}
class MyThread implements Runnable {
private CountDownLatch latch;
public MyThread(CountDownLatch latch) {
this.latch = latch;
}
@Override
public void run() {
try {
Thread.sleep(3000);
}catch (InterruptedException e){
e.printStackTrace();
}
finally {
latch.countDown();//每个子线程执行完毕后,触发一次countDown(),即计数器减1
}
}
}
代码流程分析:
-
在开始记录执行时间start;
-
在执行时创建了10个子线程,并通过
CountDownLatch
的await()
方法等待子线程执行完毕。 -
当子线程全部执行完毕后,Main线程结束了
await()
等待,继续向下执行,然后记录结束的时间end; -
最后计算
end-start
执行时间;
程序运行结果如下图所示:
以上就是关于CountDownLatch
在多线程通信中的案例学习,希望对你有所帮助~