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();
    }
}
View Code

 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 是一组线程之间的相互等待,可以类比几个驴友之间的不离不弃,共同到达某个地方,再继续出发,这样反复。

 

posted @ 2020-07-01 10:24  好好学习。天天向上  阅读(117)  评论(0)    收藏  举报