概念:
- countDownLatch这个类使一个线程等待其他线程各自执行完毕后再执行。
- 是通过一个计数器来实现的,计数器的初始值是线程的数量。每当一个线程执行完毕后,计数器的值就-1,当计数器的值为0时,表示所有线程都执行完毕,然后在闭锁上等待的线程就可以恢复工作了。
示例:
构造器
List<String> list = new ArrayList<String>();
list.add("泰隆");
list.add("游走于刀尖之上");
list.add("刀下生刀下死!");
CountDownLatch count = new CountDownLatch(list.size());//参数count为计数值
使用
System.out.println("刀锋之影:");
list.stream().forEach( str -> {
ExecutorService es = Executors.newSingleThreadExecutor();//一个线程
es.execute(new Runnable(){
@Override
public void run(){
System.out.println(str);
count.countDown();//将count值减1
System.out.println("count的值:" + count.getCount());// getCount()获取下标,由大到小
}
});
es.shutdown();
});
try {
count.await();//调用await()方法的线程会被挂起,它会等待直到count值为0才继续执行
System.out.println("W后跟平A或者Q,大招会跟人");
} catch (InterruptedException e) {
e.printStackTrace();
}
扩展:
public boolean await(long timeout, TimeUnit unit) throws InterruptedException { };
//和await()类似,只不过等待一定的时间后count值还没变为0的话就会继续执行
ExecutorService newFixedThreadPool() : 创建固定大小的线程池
ExecutorService newCachedThreadPool() : 缓存线程池,线程池的数量不固定,可以根据需求自动的更改数量。
ExecutorService newSingleThreadExecutor() : 创建单个线程池。 线程池中只有一个线程
ScheduledExecutorService newScheduledThreadPool() : 创建固定大小的线程,可以延迟或定时的执行任务
CountDownLatch:通过一个计数器来实现,await方法阻塞直到 countDown() 调用计数器归零之后释放所有等待的线程,并且任何后续的await调用立即返回。这是一次性现象 - 计数无法重置
模拟并发示例:
public class Parallellimit {
public static void main(String[] args) {
ExecutorService pool = Executors.newCachedThreadPool();
CountDownLatch cdl = new CountDownLatch(100);
for (int i = 0; i < 100; i++) {
CountRunnable runnable = new CountRunnable(cdl);
pool.execute(runnable);
}
}
}
class CountRunnable implements Runnable {
private CountDownLatch countDownLatch;
public CountRunnable(CountDownLatch countDownLatch) {
this.countDownLatch = countDownLatch;
}
@Override
public void run() {
try {
synchronized (countDownLatch) {
/*** 每次减少一个容量*/
countDownLatch.countDown();
System.out.println("thread counts = " + (countDownLatch.getCount()));
}
countDownLatch.await();//线程被挂起,后面的代码暂不执行,一直等计数为0之后,累计的所有线程一起执行
System.out.println("concurrency counts = " + (100 - countDownLatch.getCount()));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}