CountDownLatch
1、概述
CountDownLatch是java.util.concurrent中的一个同步工具类,允许一个或多个线程等待,
直到其他线程运行完后接着执行。
CountDownLatch的核心是一个构造方法和两个普通方法。
构造方法中可传入一个int类型的count值,该值代表内部计数器的初始值,一旦传入无法更改。
countDown()方法每被CountDownLatch对象调用一次,CountDownLatch内部计数器的count值就会减一。
await()方法不带参数时,它在哪个线程体中被CountDownLatch对象调用,该线程就会停在await()方法
处,直到CountDownLatch内部计数器的count值降为0,被暂停的线程体才会紧接着await()方法后的代码执行。
await()方法实际还可以存入两个参数用于设置一个时间阈值,当超过时间阈值时,即使count值没有降为
0,暂停的线程体仍然会紧接着await()方法后的代码执行。
2、场景
有了CountDownLatch的构造器和countDown、await方法。我们就可以实现两种应用场景:
①让一个线程等待,类似于主线程等待多个子线程加载资源的场景。
②让多个线程等待,类似于多线程并发执行的场景。
3、代码
package com.atguigu.juc;
import org.junit.Test;
import java.util.concurrent.CountDownLatch;
/**
* CountDownLatch
* 1、概述
* CountDownLatch是java.util.concurrent中的一个同步工具类,允许一个或多个线程等待,直到其他线程运行完后接着执行。
* CountDownLatch的核心是一个构造方法和两个普通方法,构造方法中可传入一个int类型的count值,该值代表内部计数器的初始值,
* 一旦传入无法更改。countDown()方法每被CountDownLatch对象调用一次,CountDownLatch内部计数器的count值就会减一。await()方法
* 不带参数时,它在哪个线程体中被CountDownLatch对象调用,该线程就会停在await()方法处,直到CountDownLatch内部计数器的count值
* 降为0,被暂停的线程体才会紧接着await()方法后的代码执行。await()方法实际还可以存入两个参数用于设置一个时间阈值,当超过时间
* 阈值时,即使count值没有降为0,暂停的线程体仍然会紧接着await()方法后的代码执行。await。
*
* 2、场景
* 有了CountDownLatch的构造器和countDown、await方法。我们就可以实现两种应用场景:①让一个线程等待,类似于主线程等待多个子
* 线程加载资源的场景。②让多个线程等待,类似于多线程并发执行的场景。
*
*/
public class MyCountDownLatchTest {
/**
* 让一个线程等待
* @throws InterruptedException
*/
@Test
public void oneWait() throws InterruptedException {
CountDownLatch countDownLatch = new CountDownLatch(5);
for (int i = 0; i < 5; i++) {
new Thread(
() ->{
System.out.println(Thread.currentThread().getName()+"运行结束了");
countDownLatch.countDown();//线程运行完计数器减一
}
).start();
}
countDownLatch.await();//暂停主线程,等待计数器count值为0后接着执行
System.out.println("主线程开始执行了");
}
/**
* 让多个线程等待
* @throws InterruptedException
*/
@Test
public void moreWait() throws InterruptedException {
CountDownLatch countDownLatch = new CountDownLatch(1);
for (int i = 0; i < 5; i++) {
new Thread(
() -> {
try {
countDownLatch.await();//线程刚开始执行就暂停,等待主线程发号施令。
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
System.out.println(Thread.currentThread().getName()+"运行结束了");
}
}
).start();
}
countDownLatch.countDown();//count值减一,计数器为0,所有子线程同时被唤醒执行
Thread.sleep(1000);
System.out.println("主线程执行完毕!");
}
}
onwait运行结果:
Thread-0运行结束了
Thread-1运行结束了
Thread-4运行结束了
Thread-3运行结束了
Thread-2运行结束了
主线程开始执行了
morewait运行结果:
Thread-1运行结束了
Thread-0运行结束了
Thread-3运行结束了
Thread-4运行结束了
Thread-2运行结束了
主线程执行完毕!