CountDownLatch和CyclicBarrier都有一个计数器
CountDownLatch countDownLatch = new CountDownLatch(4); CyclicBarrier cyclicBarrier = new CyclicBarrier(4)
CountDownLatch 是在 countDownLatch.countDown()执行后 4-1 等到4减到0后,就可以继续执行程序,否则会一直等待
CyclicBarrier是在cyclicBarrier.await()执行后 也是4-1 等到4减到0后,也可以继续执行程序,否则一直会等待。
两者有什么区别呢?举个例子
办公室有4个人
CountDownLatch是 你们4个人干完活了,等你们都干完活了,我来讲两句
CyclicBarrier是你们4个干完活了,等都干完活了,你们接着继续干
闭锁CountDownLatch用于等待事件,而栅栏CyclicBarrier用于等待其他线程。
CountDownLatch是4个线程都执行完countDown后,程序继续向下运行,后面的事和4个线程无关,和CountDownLatch.await()此方法等待你们4个干完活有关。这里类似 你自己diy电脑,买了主机,cpu,电源 ,主板,等等,必须等所有快递到了之后你才能安装电脑。
CyclicBarrier是4个线程执行到某一步后都开始await,等等待的人到齐后继续干活。这里类似王者荣耀,10个人进入加载页面后,必须等10个人全部加载完成后才能进入游戏界面
来demo
@Testpublic void testCount() throws InterruptedException {ArrayList<String> list = Lists.newArrayList("cpu", "显示器", "主板", "电源", "机箱", "鼠标", "键盘");int size = list.size();ExecutorService executorService = Executors.newFixedThreadPool(size);//程序计数器CountDownLatch countDownLatch = new CountDownLatch(size);for (int i = 0; i < size; i++) {int finalI = i;executorService.submit(() -> {System.out.println("快递【"+list.get(finalI)+"】已送达");countDownLatch.countDown();long count = countDownLatch.getCount();System.out.println("快递总共有"+size+"个,目前还剩下"+count+"个未到达");});Thread.sleep(10);}Thread.sleep(1000);countDownLatch.await();System.out.println("快递已经到达完毕,开始组装玩游戏");//线程池 等待10sexecutorService.awaitTermination(10, TimeUnit.SECONDS);//关闭线程 其实是将线程状态设置为中断标志 必须等待所有线程处理完任务,才能完全关闭executorService.shutdown();}
@Testpublic void testCyclicBarrier() throws InterruptedException {ArrayList<String> list = Lists.newArrayList("user1", "user2", "user3", "user4", "user5", "user6", "user7", "user8", "user9", "user10");int size = list.size();ExecutorService executorService = Executors.newFixedThreadPool(size);CyclicBarrier cyclicBarrier = new CyclicBarrier(size, () -> {System.out.println("所有人加载完毕,欢迎进入游戏!");});for (int i = 0; i < list.size(); i++) {int finalI = i;executorService.submit(new Thread(() -> {try {System.out.println("用户【" + list.get(finalI) + "】选完英雄,进入加载界面,等待其他人加载.....");cyclicBarrier.await(); // 等待其他线程到齐,到齐了之后就会执行一次System.out.println("用户【" + list.get(finalI) + "】加载游戏完成,进入游戏,开始游戏");} catch( Exception e) {e.printStackTrace();}}));}executorService.awaitTermination(10, TimeUnit.SECONDS);executorService.shutdown();}