1. 1 不可撤销
  2. 2 小年兽 程嘉敏
  3. 3 手放开 李圣杰
  4. 4 迷人的危险3(翻自 dance flow) FAFA
  5. 5 山楂树之恋 程佳佳
  6. 6 summertime cinnamons / evening cinema
  7. 7 不谓侠(Cover 萧忆情Alex) CRITTY
  8. 8 神武醉相思(翻自 优我女团) 双笙
  9. 9 空山新雨后 音阙诗听 / 锦零
  10. 10 Wonderful U (Demo Version) AGA
  11. 11 广寒宫 丸子呦
  12. 12 陪我看日出 回音哥
  13. 13 春夏秋冬的你 王宇良
  14. 14 世界が终わるまでは… WANDS
  15. 15 多想在平庸的生活拥抱你 隔壁老樊
  16. 16 千禧 徐秉龙
  17. 17 我的一个道姑朋友 双笙
  18. 18 大鱼  (Cover 周深) 双笙
  19. 19 霜雪千年(Cover 洛天依 / 乐正绫) 双笙 / 封茗囧菌
  20. 20 云烟成雨(翻自 房东的猫) 周玥
  21. 21 情深深雨濛濛 杨胖雨
  22. 22 Five Hundred Miles Justin Timberlake / Carey Mulligan / Stark Sands
  23. 23 斑马斑马 房东的猫
  24. 24 See You Again Wiz Khalifa / Charlie Puth
  25. 25 Faded Alan Walker / Iselin Solheim
  26. 26 Natural J.Fla
  27. 27 New Soul Vox Angeli
  28. 28 ハレハレヤ(朗朗晴天)(翻自 v flower) 猫瑾
  29. 29 像鱼 王贰浪
  30. 30 Bye Bye Bye Lovestoned
  31. 31 Blame You 眠 / Lopu$
  32. 32 Believer J.Fla
  33. 33 书信 戴羽彤
  34. 34 柴 鱼 の c a l l i n g【已售】 幸子小姐拜托了
  35. 35 夜空中最亮的星(翻自 逃跑计划) 戴羽彤
  36. 36 慢慢喜欢你 LIve版(翻自 莫文蔚) 戴羽彤
  37. 37 病变(翻自 cubi) 戴羽彤
  38. 38 那女孩对我说 (完整版) Uu
  39. 39 绿色 陈雪凝
  40. 40 月牙湾 LIve版(翻自 F.I.R.) 戴羽彤
夜空中最亮的星(翻自 逃跑计划) - 戴羽彤
00:00 / 04:10

夜空中最亮的星 能否听清

那仰望的人 心底的孤独和叹息

夜空中最亮的星 能否记起

那曾与我同行 消失在风里的身影

我祈祷拥有一颗透明的心灵

和会流泪的眼睛

给我再去相信的勇气

越过谎言去拥抱你

每当我找不到存在的意义

每当我迷失在黑夜里

噢喔喔 夜空中最亮的星

请指引我靠近你

夜空中最亮的星 是否知道

那曾与我同行的身影 如今在哪里

夜空中最亮的星 是否在意

是等太阳先升起 还是意外先来临

我宁愿所有痛苦都留在心底

也不愿忘记你的眼睛

哦 给我再去相信的勇气

哦 越过谎言去拥抱你

每当我找不到存在的意义

每当我迷失在黑夜里

噢喔喔 夜空中最亮的星

请照亮我向前行 哒~

我祈祷拥有一颗透明的心灵

和会流泪的眼睛 哦

给我再去相信的勇气

哦 越过谎言去拥抱你

每当我找不到存在的意义

每当我迷失在黑夜里

噢喔喔 夜空中最亮的星

请照亮我向前行

多线程之countDownLatch

前言

原本是昨天分享countDownLatch相关知识点的,但是昨天粗略看写了,发现自己对countDownLatch的认知还不够,所以就半道分享了常用的三种多线程线程安全解决方案的性能比较,虽然过程中翻车了,但是还是有收获的,也不亏。今天又去看了下count的相关知识,然后做了一个小demo,感觉有点眉目了,所以我们来继续看countDownLatch

countDownLatch

countDownLathjdk1.5引入的一个新特性,它的出现主要是为了解决某些应用场景下多线程运行顺序的问题。我们在定义countDownLatch的时候,需要指定它的count大小,它就是通过这个count来控制多线程运行顺序的。

它有两个核心的方法countDownawaitcountDown的作用是当线程执行完后把count减一,只能用一次;await方法是判断count是否减为0,这个方法本身是阻塞的,如果count不是0await后面的代码是不会被执行的。

接下来,我们通过一段示例代码来看下countDownLatch的基本用法:

public class Example {
    private static AtomicInteger count = new AtomicInteger(0);
    private static final int SIZE_FIRST = 100;
    private static final int SIZE_SECOND = 50;

    public static void main(String[] args) throws InterruptedException {
        ExecutorService executorService = Executors.newCachedThreadPool();
        final CountDownLatch countDownLatch = new CountDownLatch(SIZE_FIRST);
        for (int i = 0; i < SIZE_FIRST; i++) {
            executorService.execute(new Task1(countDownLatch));
        }
        countDownLatch.await();
        final CountDownLatch countDownLatch2 = new CountDownLatch(SIZE_SECOND);
        for (int i = 0; i < SIZE_SECOND; i++) {
            executorService.execute(new Task2(countDownLatch2));
        }
        countDownLatch2.await();
        for (int i = 0; i < SIZE_SECOND; i++) {
            executorService.execute(new Task3());
        }
        executorService.shutdown();
    }


    static class Task1 implements Runnable {
        private final CountDownLatch countDownLatch;

        Task1(CountDownLatch countDownLatch) {
            this.countDownLatch = countDownLatch;
        }


        @Override
        public void run() {
            System.out.println("Task1: " + count.getAndIncrement());
            this.countDownLatch.countDown();
        }
    }

    static class Task2 implements Runnable {
        private final CountDownLatch countDownLatch;

        public Task2(CountDownLatch countDownLatch) {
            this.countDownLatch = countDownLatch;
        }

        @Override
        public void run() {
            System.out.println("Task2: " + count.getAndIncrement());
            this.countDownLatch.countDown();
        }
    }

    static class Task3 implements Runnable {
        @Override
        public void run() {
            System.out.println("Task3: " + count.getAndIncrement());
        }
    }

}

这里我分别定义了三个线程,前两个线程构造的时候都需要传入countDownLatch,然后在run方法的尾部执行countDown方法,也就是每启动一个线程,count减一。

我们这里还定义了两个countDownLatch,初始值分别是10050,他们分别对应线程task1task2的执行次数。

在线程task1task2之间我们执行第一个countDownLatchawait方法,控制线程task1task2的执行顺序,确保线程task1先执行;

在线程task2和线程task3之间我们执行第二个countDownLatchawait方法,控制线程task2task3的执行顺序,确保线程task2先执行。

然后,我们运行上面的代码,会得到如下结果:

在以上结果中,我们可以看到,不论你执行多少次,线程运行顺序都是task1task2task3,当然await方法之前的执行顺序我们是没有办法控制的。

总结

从上面演示结果来看,countDownLatch主要是用来控制多线程运行顺序的,特别适合多个线程协同运行但是有顺序要求的业务,更多应用场景大家可以好好研究,我们今天的内容就到这里吧!

posted @ 2021-07-15 13:29  云中志  阅读(138)  评论(0编辑  收藏  举报