CountDownLatch和CyclicBarrier的区别
CountDownLatch代码演示(Demo1):
public class CountDownLatchDemo { static CountDownLatch countDownLatch = new CountDownLatch(6); public static void main(String[] args) throws Exception { for (int i = 1; i < 7; i++) { new Thread(()->{ System.out.println(Thread.currentThread().getName()); countDownLatch.countDown(); }, EnumDemo.getEnumInfo(i).getCountry()+"被灭").start(); } countDownLatch.await(); System.out.println("中国统一天下,OH YEAH"); } }
public enum EnumDemo { ONE(1,"法国"), TWO(2,"美国"), THREE(3,"泰国"), FOUR(4,"日本"), FIVE(5,"韩国"), SIX(6,"德国"); private Integer id; private String country; EnumDemo(Integer id, String country) { this.id = id; this.country = country; } public static EnumDemo getEnumInfo(int index){ EnumDemo[] EnumArry = EnumDemo.values(); for(EnumDemo element : EnumArry){ if(index == element.getId()){ return element; } } return null; }; public Integer getId() { return id; } public String getCountry() { return country; } public void setId(Integer id) { this.id = id; } public void setCountry(String country) { this.country = country; }
CountDownLatch代码演示(Demo2):
public class CountDownLatchExample { private static CountDownLatch countDownLatch = new CountDownLatch(2); public static void main(String[] args) throws InterruptedException { // 这里不推荐这样创建线程池,最好通过 ThreadPoolExecutor 手动创建线程池 ExecutorService executorService = Executors.newFixedThreadPool(2); executorService.submit(() -> { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } finally { log.info("Thread-1 执行完毕"); //计数器减1 countDownLatch.countDown(); } }); executorService.submit(() -> { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } finally { log.info("Thread-2 执行完毕"); //计数器减1 countDownLatch.countDown(); } }); log.info("主线程等待子线程执行完毕"); log.info("计数器值为:" + countDownLatch.getCount()); countDownLatch.await(); log.info("计数器值为:" + countDownLatch.getCount()); log.info("主线程执行完毕"); executorService.shutdown(); } }
CycliBarrier代码演示1:
public class CyclicBarrierDemo { static CyclicBarrier cyclicBarrier = new CyclicBarrier(6,()-> System.out.println("大家都来了,那我们开始开会了")); public static void main(String[] args) { for (int i = 0; i < 6; i++) { new Thread(()->{ System.out.println("先到的先暂时等一下:"+Thread.currentThread().getName()); try { cyclicBarrier.await(); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } }).start(); } } }
CycliBarrier代码演示2:
public class CountDownLatchTimeoutExample { private static CountDownLatch countDownLatch = new CountDownLatch(2); public static void main(String[] args) throws InterruptedException { // 这里不推荐这样创建线程池,最好通过 ThreadPoolExecutor 手动创建线程池 ExecutorService executorService = Executors.newFixedThreadPool(2); executorService.submit(() -> { try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } finally { log.info("Thread-1 执行完毕"); //计数器减1 countDownLatch.countDown(); } }); executorService.submit(() -> { try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } finally { log.info("Thread-2 执行完毕"); //计数器减1 countDownLatch.countDown(); } }); log.info("主线程等待子线程执行完毕"); log.info("计数器值为:" + countDownLatch.getCount()); countDownLatch.await(2, TimeUnit.SECONDS); log.info("计数器值为:" + countDownLatch.getCount()); log.info("主线程执行完毕"); executorService.shutdown(); } }
总结:CountDownLatch 主要用来解决一个线程等待多个线程的场景,可以类比旅游团团长要等待所有游客到齐才能去下一个景点。
而 CyclicBarrier 是一组线程之间的相互等待,可以类比几个驴友之间的不离不弃,共同到达某个地方,再继续出发,这样反复。
浙公网安备 33010602011771号