16-Java5的CountDownLatch同步工具
范例:3个运动员比赛,1个裁判,各个运动员到场后,准备接收裁判的命令,当裁判发布命令后,各个运动员争先抢后各就各位(时间不一样,随机),
每个运动员就位后,都要等待裁判发号施令,当三个运动员都各就各位了,裁判发送命令,三个运动员开始执行任务,等到三个运动员都完成比赛后,
裁判才可以宣布比赛结果,比赛结束!
package cn.itcast.demo.thread; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class CountDownLatchTest { public static void main(String[] args) { // 创建线程池对象 ExecutorService executorService = Executors.newCachedThreadPool(); // 创建计数器对象 final CountDownLatch orderLatch = new CountDownLatch(1); // 主线程计数器(裁判) final CountDownLatch anwserLatch = new CountDownLatch(3); // 子线程计数器(3个运动员) // 子线程动作 for (int i=0; i<3; i++) { Runnable runnable = new Runnable() { @Override public void run() { try { System.out.println("线程[ " + Thread.currentThread().getName() + " ]正准备接受命令"); orderLatch.await(); // 等待主线程(裁判)发号施令 System.out.println("线程[ " + Thread.currentThread().getName() + " ]已接受命令"); Thread.sleep((long)Math.random()*10000+2000L); // 这句模拟各运动员执行任务的时间 System.out.println("线程[ " + Thread.currentThread().getName() + " ]回应响应结果"); anwserLatch.countDown(); // 回应响应结果,子线程计数器数量减1,当减到0时,下面的anwserLatch.await();就放行 } catch (Exception e) { e.printStackTrace(); } } }; executorService.execute(runnable); } // 主线程动作 try { Thread.sleep((long)Math.random()*10000); // 这句模拟各运动员就位后到裁判发布命令的等待时间 System.out.println("线程[ " + Thread.currentThread().getName() + " ]即将发布命令!"); orderLatch.countDown(); // 把计数器原始值1减1后就是0,当为零时,上面的orderLatch.await();就放行 System.out.println("线程[ " + Thread.currentThread().getName() + " ]已经发布命令,正在等待结果"); anwserLatch.await(); // 等待响应结果(当三个线程都执行完各自的任务后就放行) System.out.println("线程[ " + Thread.currentThread().getName() + " ]已经收到所有响应结果,比赛结束!"); } catch (Exception e) { e.printStackTrace(); } executorService.shutdown(); } }
打印结果:
线程[ pool-1-thread-1 ]正准备接受命令 线程[ main ]即将发布命令! 线程[ pool-1-thread-3 ]正准备接受命令 线程[ pool-1-thread-3 ]已接受命令 线程[ pool-1-thread-2 ]正准备接受命令 线程[ main ]已经发布命令,正在等待结果 线程[ pool-1-thread-2 ]已接受命令 线程[ pool-1-thread-1 ]已接受命令 线程[ pool-1-thread-3 ]回应响应结果 线程[ pool-1-thread-2 ]回应响应结果 线程[ pool-1-thread-1 ]回应响应结果 线程[ main ]已经收到所有响应结果,比赛结束!