CountDownLatch と CyclicBarrier の学習

CountDownLatch と CyclicBarrier の両方にカウンターがあります

CountDownLatch countDownLatch = 新しい CountDownLatch(4); 
CyclicBarrier cyclicBarrier = 新しい CyclicBarrier(4)

countDownLatch.countDown() 実行後の CountDownLatch は 4-1 です。4 が 0 に減った後はプログラムの実行を続行できますが、それ以外の場合は待機し続けます。

CyclicBarrier.await() の実行後も CyclicBarrier は 4-1 になります。4 が 0 に減った後はプログラムの実行を続行できますが、それ以外の場合は常に待機します。

両者の違いは何ですか? 例えば

オフィスには4人います

CountDownLatch は 4 人で作業を終えるためのものです。皆さんの作業が完了したら、私から一言言わせてください。

サイクリックバリアは4人で作業を終えるためのもので、全員が終わったら作業を続けることができます。

ロック CountDownLatch はイベントを待機するために使用され、バリア CyclicBarrier は他のスレッドを待機するために使用されます。

CountDownLatch は、4 つのスレッドすべてが countDown を実行した後、プログラムが下方向に実行し続けることを意味します。次のことは 4 つのスレッドとは関係ありませんが、4 つのスレッドが終了するのを待機している CountDownLatch.await() メソッドと関係があります。彼らの仕事。これは、ホスト、CPU、電源、マザーボードなどを購入し、コンピューターを設置する前に宅配業者がすべて到着するまで待たなければならないため、自分でコンピューターを DIY するのと似ています。

CyclicBarrier は、4 つのスレッドすべてが特定のステップの実行後に待機を開始し、待機している人がすべて到着した後も動作を継続することを意味します。これは King of Glory と似ており、10 人がローディング ページに入った後、ゲーム インターフェイスに入る前に 10 人全員がロードされるまで待つ必要があります。

来demo

    @Test
    public 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("快递已经到达完毕,开始组装玩游戏");
        //线程池 等待10s
        executorService.awaitTermination(10, TimeUnit.SECONDS);
        //关闭线程 其实是将线程状态设置为中断标志  必须等待所有线程处理完任务,才能完全关闭
        executorService.shutdown();
    }

 

    @Test
    public 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();
    }

おすすめ

転載: blog.csdn.net/cclovezbf/article/details/131943106