CountDownLatch是JDK提供的一个同步工具,它可以让一个或多个线程等待,一直等到其他线程中执行完成一组操作。
提问:CountDownLatch有哪些常用的方法?
答:有countDown方法和await方法,CountDownLatch在初始化时,需要指定用给定一个整数作为计数器。当调用countDown方法时,计数器会被减1;当调用await方法时,如果计数器大于0时,线程会被阻塞,一直到计数器被countDown方法减到0时,线程才会继续执行。计数器是无法重置的,当计数器被减到0时,调用await方法都会直接返回。
提问:调用countDown
方法时,线程也会阻塞嘛?
不会的,调用countDown
的线程可以继续执行,不需要等待计数器被减到0,只是调用await方法的线程需要等待。
具体的一个示例代码如下(寻找不同的7颗龙珠,集齐之后进行打印输出)
package com.JUC;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
public class CountDownLatchTest {
private final static Random random = new Random();
static class SearchTask implements Runnable{
private Integer id;
private CountDownLatch latch;
public SearchTask(Integer id,CountDownLatch latch){
this.id = id;
this.latch = latch;
}
@Override
public void run() {
System.out.println("开始寻找 "+id +"号龙珠");
int seconds = random.nextInt(10);
try {
Thread.sleep(seconds*1000);
}catch (InterruptedException e){
e.printStackTrace();
}
System.out.println("耗费 "+seconds+"秒找到了 "+id +"号龙珠");
latch.countDown();
}
}
public static void main(String[] args) {
List<Integer> idList = Arrays.asList(1,2,3,4,5,6,7);
CountDownLatch countDownLatch = new CountDownLatch(idList.size());
for (Integer id: idList) {
Thread thread = new Thread(new SearchTask(id,countDownLatch));
thread.start();
}
try{
countDownLatch.await();
}catch (InterruptedException e){
e.printStackTrace();
}
System.out.println("集齐了7颗龙珠!");
}
}
输出结果:
开始寻找 2号龙珠
开始寻找 4号龙珠
开始寻找 3号龙珠
开始寻找 1号龙珠
开始寻找 5号龙珠
开始寻找 6号龙珠
开始寻找 7号龙珠
耗费 2秒找到了 3号龙珠
耗费 2秒找到了 7号龙珠
耗费 2秒找到了 1号龙珠
耗费 3秒找到了 6号龙珠
耗费 3秒找到了 4号龙珠
耗费 4秒找到了 2号龙珠
耗费 5秒找到了 5号龙珠
集齐了7颗龙珠! //(这里是等待上面集齐之后再打印出来的)