唐僧喜欢小龙女

导航

CountDownLatch

1、CountDownLatch 是什么

CountDownLatch 是一个减法计数器

2、阻塞一个线程

/**
 *
 *  减法计数器
 *
 */
public class CountDownLatchDemo {

    private String[] strings = new String[]{"ass","sss","cdss"};

    public static void main(String[] args) {
        CountDownLatchDemo countDownLatchDemo = new CountDownLatchDemo();
        countDownLatchDemo.prints();
    }


    /**
     *
     *  主线程 必须要等到别的线程执行完了,才能向下走,这时候就用到了CountDownLatch。
     */
    public void prints(){
        CountDownLatch countDownLatch = new CountDownLatch(6);
        for (int i = 0; i < 6; i++) {
            new Thread(()->{
                System.out.println("同学"+Thread.currentThread().getName()+"   出去了");
                countDownLatch.countDown();  //这里就是计数器减一
            },String.valueOf(i)).start();

        }

        try {
            countDownLatch.await(); //等待计数器归零,await 被唤醒 然后代码在向下执行。
        }catch (Exception e){

        }
        System.out.println(" 教室里面没有人了 close door!");

    }

}

 

3、阻塞多个线程

/**
 *
 *  模拟一个并发的例子
 *
 */
public class CountDownLatchDemo2 {
    private static volatile int num = 0;
    public static void main(String[] args) throws InterruptedException{
        CountDownLatchDemo2 countDownLatchDemo2 = new CountDownLatchDemo2();
        countDownLatchDemo2.prints();


    }

    public void prints() throws InterruptedException{
        CountDownLatch countDownLatch = new CountDownLatch(1);
        for (int i = 0; i < 10; i++) {
            new Thread(()->{
                try {
                    countDownLatch.await(); //等待计数器归零,await 被唤醒 然后代码在向下执行。
                    for (int j= 0;j<100;j++){
                        TimeUnit.MILLISECONDS.sleep(20);
                        num ++;
                    }
                }catch (Exception e){

                }
            },String.valueOf(i)).start();
        }

        System.out.printf("休息 2秒 \n");
        TimeUnit.MILLISECONDS.sleep(2000);
        countDownLatch.countDown(); //计数器减一

        System.out.printf("再休息 2秒 \n");
        //这里也必须的要暂停两秒,否则下面 输出num 值的时候 很可能是0 原因是main 线程先执行,上面的几个线程还没有
        //执行呢。
        TimeUnit.MILLISECONDS.sleep(2000);

        System.out.printf("num is = "+ num);
    }
}

 

4、模拟了一个需要使用cas来解决问题的例子

/**
 *
 *  这里模拟了一个需要使用cas来解决问题的例子。
 *
 */
public class CountDownLatchDemo1 {
    private static volatile  int num = 0;
    public static void main(String[] args) {
        CountDownLatchDemo1 countDownLatchDemo1 = new CountDownLatchDemo1();
        countDownLatchDemo1.prints();
    }
    public void prints(){
        CountDownLatch countDownLatch = new CountDownLatch(10);
        for (int i = 0; i < 10; i++) {
            new Thread(()->{
                try{
                    for (int j = 0; j<100;j++){
                        //这里需要模拟一个时间,否则num 最后的结果一般是 1000
                        TimeUnit.MILLISECONDS.sleep(200);
                        num ++;
                    }
                }catch (Exception e){

                }finally {
                    countDownLatch.countDown();  //这里就是计数器减一
                }
            },String.valueOf(i)).start();
        }

        try {
            countDownLatch.await(); //等待计数器归零,await 被唤醒 然后代码在向下执行。
        }catch (Exception e){

        }

        System.out.println(" 教室里面没有人了 close door!"+num);

    }

}

 

posted on 2021-05-17 08:53  与时具进&不忘初心  阅读(43)  评论(0编辑  收藏  举报