2.CountDownLatch CountDownLatch主要起倒计时计数器作用,它主要有两个方法await()和countDown()。一旦某个线程调用await()方法,那么该线程就会阻塞,等待CountDownLatch计数器倒计时归零,需要注意的是尽管线程调用await()方法后会阻塞,但是CountDownLatch允许别的线程调用countDown()方法,将计数器减一。也就是说调用计时器的线程阻塞后,可以利用别的线程控制调用线程何时从新开始运行。
CountDownLatch 是一个通用同步工具,它有很多用途。将计数 1 初始化的CountDownLatch 用作一个简单的开/关锁存器,或入口:在通过调用 countDown() 的线程打开入口前,所有调用await 的线程都一直在入口处等待。用 N 初始化的 CountDownLatch 可以使一个线程在 N个线程完成某项操作之前一直等待,或者使其在某项操作完成 N 次之前一直等待。 CountDownLatch 的一个有用特性是,它不要求调用countDown 方法的线程等到计数到达零时才继续,而在所有线程都能通过之前,它只是阻止任何线程继续通过一个 await 。 package cn.thread;
import java.util.concurrent.CountDownLatch;
/**
* 模拟运动员跑步
* 同组的运动必须都准备就绪后才能出发
*
*/
public class CountDownLatchTest {
private final static int GROUP_SIZE = 5;
public static void main(String []args) {
processOneGroup("分组1");
processOneGroup("分组2");
}
private static void processOneGroup(final String groupName) {
final CountDownLatch start_count_down = new CountDownLatch(1);//起到锁的作用
final CountDownLatch end_count_down = new CountDownLatch(GROUP_SIZE);//模拟运动员计数器
System.out.println( groupName + "比赛开始:");
for(int i = 0 ; i < GROUP_SIZE ; i++) {
new Thread(String.valueOf(i)) {
public void run() {
System.out.println("【" + groupName + "】,第" + this.getName() + " 号线程,我已经准备就绪!");
try {
start_count_down.await();//进行阻塞,等待其他运动员准备就绪
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("【" + groupName + "】,第" + this.getName() + " 号线程,我已执行完成!");
end_count_down.countDown();//其中一个运动员完成,计算器-1
}
}.start();
}
try {
Thread.sleep(1000);//让所有运动都准备好
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(groupName+"预备!Go!!!");
start_count_down.countDown();//解锁,运动员开始赛跑
try {
end_count_down.await();//阻塞父线程,等到所有运动员跑完后(end_count_down为0),再往下执行
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println( groupName + "比赛结束!");
}
}
运行结果 分组1比赛开始: 【分组1】,第0 号线程,我已经准备就绪! 【分组1】,第2 号线程,我已经准备就绪! 【分组1】,第3 号线程,我已经准备就绪! 【分组1】,第1 号线程,我已经准备就绪! 【分组1】,第4 号线程,我已经准备就绪! 分组1预备!Go!!! 【分组1】,第0 号线程,我已执行完成! 【分组1】,第1 号线程,我已执行完成! 【分组1】,第4 号线程,我已执行完成! 【分组1】,第3 号线程,我已执行完成! 【分组1】,第2 号线程,我已执行完成! 分组1比赛结束! 分组2比赛开始: 【分组2】,第1 号线程,我已经准备就绪! 【分组2】,第0 号线程,我已经准备就绪! 【分组2】,第3 号线程,我已经准备就绪! 【分组2】,第2 号线程,我已经准备就绪! 【分组2】,第4 号线程,我已经准备就绪! 分组2预备!Go!!! 【分组2】,第1 号线程,我已执行完成! 【分组2】,第0 号线程,我已执行完成! 【分组2】,第2 号线程,我已执行完成! 【分组2】,第3 号线程,我已执行完成! 【分组2】,第4 号线程,我已执行完成! 分组2比赛结束! |