CountDownLatch可以使一个获多个线程等待其他线程各自执行完毕后再执行。
CountDownLatch 定义了一个计数器,和一个阻塞队列, 当计数器的值递减为0之前,阻塞队列里面的线程处于挂起状态,当计 数器递减到0时会唤醒阻塞队列所有线程,这里的计数器是一个标志,可以表示一个任务一个线程,也可以表示一个倒计时器, CountDownLatch可以解决那些一个或者多个线程在执行之前必须依赖于某些必要的前提业务先执行的场景。
CountDownLatch(int count); //构造方法,创建一个值为count 的计数器。 await();//阻塞当前线程,将当前线程加入阻塞队列。 await(long timeout, TimeUnit unit);//在timeout的时间之内阻塞当前线程,时间一过则当前线程可以执行, countDown();//对计数器进行递减1操作,当计数器递减至0时,当前线程会去唤醒阻塞队列里的所有线程。
三个工人全部工作完,老板检查工作(一个主线程,三个子线程)
public class Worker implements Runnable { private CountDownLatch downLatch; private String name; public Worker(CountDownLatch downLatch, String name){ this.downLatch = downLatch; this.name = name; } public void run() { this.doWork(); try{ TimeUnit.SECONDS.sleep(new Random().nextInt(10)); }catch(InterruptedException ie){ } System.out.println(this.name + "-结束-工作!"); this.downLatch.countDown(); } private void doWork(){ System.out.println(this.name + "-开始-干活!"); } } public class BossWork implements Runnable{ private CountDownLatch downLatch; public BossWork(CountDownLatch downLatch){ this.downLatch = downLatch; } public void run() { System.out.println("老板等待所有的工人干完活......"); try { this.downLatch.await(); } catch (InterruptedException e) { } System.out.println("工人活都干完了,老板开始检查了!"); } } public static void main(String[] args) { //创建多线程 ExecutorService executor = Executors.newCachedThreadPool(); CountDownLatch downLatch = new CountDownLatch(3); Worker w1 = new Worker(downLatch,"张三"); Worker w2 = new Worker(downLatch,"李四"); Worker w3 = new Worker(downLatch,"王五"); BossWork boss = new BossWork(downLatch); executor.execute(w3); executor.execute(w2); executor.execute(w1); executor.execute(boss); executor.shutdown(); }结果:
王五-开始-干活! 老板等待所有的工人干完活...... 张三-开始-干活! 李四-开始-干活! 李四-结束-工作! 张三-结束-工作! Disconnected from the target VM, address: '127.0.0.1:49416', transport: 'socket' 王五-结束-工作! 工人活都干完了,老板开始检查了!