CountDownLatch是一个同步工具类,它允许一个或多个线程一直等待,直到其他线程的操作执行完后再执行。
CountDownLatch(int count):构造一个用给定计数初始化的 CountDownLatch。
线程阻塞:await():使当前线程在锁存器倒计数至零之前一直等待,除非线程被中断。
线程释放:countDown所描述的是:递减锁存器的计数,如果计数到达零,则释放所有等待的线程。
await()方法用于阻塞当前线程,当其他线程都执行countDown()之后,计数器为0,执行后面的代码,否则一直阻塞当前线程。
countDown()方法当前线程执行完指定的逻辑之后,计数器-1。
import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class CountDownLatchTest {
public static void main(String[] args) throws InterruptedException {
// 用于判断发令之前运动员是否已经完全进入准备状态,需要等待10个运动员,所以参数为10
final CountDownLatch runner = new CountDownLatch(10);
// 用于判断裁判是否已经发令,只需要等待一个裁判,所以参数为1
final CountDownLatch referee = new CountDownLatch(1);
ExecutorService executor = Executors.newCachedThreadPool();
for(int i=0;i<10;i++) {
final int offset = i;
executor.execute(new Runnable() {
@Override
public void run() {
try {
TimeUnit.MILLISECONDS.sleep(new Random().nextInt(1000));
System.out.println("运动员-"+offset+"-准备完毕#"+Thread.currentThread().getName());
//当前线程准备完毕,计数器-1
runner.countDown();
//等待裁判准备,阻塞当前线程
referee.await();
System.out.println("运动员-"+offset+"-开始跑#"+Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
//所有运动员准备完毕之后,执行后面的逻辑
runner.await();
//裁判准备完毕
referee.countDown();
System.out.println("裁判:所有运动员准备完毕,开始……");
executor.shutdown();
}
}