之前遇到一次面试问到:CycliBarriar和CountdownLatch有啥区别,由于不了解CycliBarriar导致很尴尬。
先来了解下CountdownLatch,CountdownLatch就是一个同步计数器,楼主经常在线程等待执行完成的场景中,使用CountdownLatch。
/**
* 计数器测试主函数
* <li>初始化大小为10的计数器
* <li>每个线程执行完进行计数器-1
* <li>如有线程未执行完,等待执行
* <li>结束
* @author
* @param args
*/
public static void main(String[] args) {
int taskNum = 10;
// 初始化计数器
CountDownLatch latch = new CountDownLatch(taskNum);
for (int i = 0; i < taskNum; i++) {
final int index = i + 1;
Thread t = new Thread(new Runnable() {
@Override
public void run() {
try {
System.out.println("---------start--------- No is " + index);
} finally {
// 每执行完一个线程,计数器-1
latch.countDown();
}
}
});
// 开启线程任务
t.start();
}
// 如果有未执行的线程,等待执行
if (latch.getCount() > 0) {
System.out.println("-----------未执行线程数---------num is " + latch.getCount());
try {
latch.await();
} catch (InterruptedException e) {
System.out.println("------------Thread is interrupted-----------");
}
}
CountDownLatch一个同步辅助类,从包路径java.util.concurrent可知,这个类是涉及线程并发场景的。在完成一组正在其他线程中执行的操作之前,它允许多个线程一直等待。用给定的计数 初始化 CountDownLatch。由于调用了 countDown() 方法,所以在当前计数到达零之前,await 方法会一直受阻塞。之后,会释放所有等待的线程,await 的所有后续调用都将立即返回。这种现象只出现一次——计数无法被重置。用来等待其他线程执行完成。
那么问题来了,这个和Thread.join()有啥区别呢?举个栗子。
有10个工人都能能完成工作,一共有10个工作。假设每个工人完成一个工作需要1天
join就是让每个工人按顺序完成1-10个工作,一共需要10天完成。
CountDownLatch就类似于工厂,假设这个工厂最大容量为5个人,这样就只需要2天就能完成。