亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

詳解Java中CountDownLatch的用法

 更新時(shí)間:2023年05月17日 10:39:15   作者:tizzybepeacejoy  
這篇文章主要為大家詳細(xì)介紹了Java中CountDownLatch類(lèi)的用法,本文通過(guò)一些簡(jiǎn)單的示例進(jìn)行了簡(jiǎn)單介紹,感興趣的小伙伴可以跟隨小編一起了解一下

CountDownLatch使用場(chǎng)景

線(xiàn)程計(jì)數(shù)器 用于線(xiàn)程執(zhí)行任務(wù),計(jì)數(shù) 等待線(xiàn)程結(jié)束

用法一: 等待所有的事情都做完

        //程序計(jì)數(shù)器
        CountDownLatch countDownLatch = new CountDownLatch(10000);
        //2個(gè)線(xiàn)程
        ExecutorService executorService = Executors.newFixedThreadPool(2);
        AtomicInteger count = new AtomicInteger(0);
        for (int i = 0; i < 10000; i++) {
            executorService.submit(() -> {
                count.getAndIncrement();//自增
                System.out.println(Thread.currentThread().getName() + " : " + count.get());
                countDownLatch.countDown();
            });
        }
        //線(xiàn)程池 等待10s
        executorService.awaitTermination(10, TimeUnit.SECONDS);
        //關(guān)閉線(xiàn)程 其實(shí)是將線(xiàn)程狀態(tài)設(shè)置為中斷標(biāo)志  必須等待所有線(xiàn)程處理完任務(wù),才能完全關(guān)閉
        executorService.shutdown();
        //必須等待兩個(gè)線(xiàn)程執(zhí)行完   會(huì)一直等待下去,當(dāng)然也可以設(shè)置指定時(shí)間等待超時(shí) await(timeout);
        countDownLatch.await();
    }

始終是2個(gè)線(xiàn)程在做事情,等2個(gè)線(xiàn)程做完事情才會(huì)停止下來(lái)。

用法二:假設(shè)2個(gè)線(xiàn)程做事情,剛開(kāi)始并行做事情,等一個(gè)執(zhí)行完成之后,另一個(gè)才能執(zhí)行(實(shí)際還是計(jì)數(shù))

        //程序計(jì)數(shù)器
        CountDownLatch countDownLatch = new CountDownLatch(1);
        Thread thread1 =new Thread(()->{
                System.out.println(" ---------------- 1  準(zhǔn)備 ---------------- ");
                try {
                    countDownLatch.await();
                    System.out.println(" ---------------- 1  finsh  ---------------- ");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
        });
        thread1.start();
        Thread thread2 = new Thread(() -> {
                System.out.println(" ---------------- 2  準(zhǔn)備 ---------------- ");
                try {
                    Thread.sleep(1_000);
                    System.out.println(" ---------------- 異步做事情  ---------------- ");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {
                    countDownLatch.countDown();
                }
        });
        thread2.start();
        //main 在等main 結(jié)束  死循環(huán)
        Thread.currentThread().join();

剛開(kāi)始一起在準(zhǔn)備狀態(tài),然后分開(kāi)做事情

用法三:退出條件

中斷一個(gè)線(xiàn)程 count 到0

        //程序計(jì)數(shù)器
        CountDownLatch countDownLatch = new CountDownLatch(1);
        Thread thread = Thread.currentThread();
        Thread thread1 = new Thread(() -> {
            try {
             Thread.sleep(10_000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            // 1 中斷條件1
		    countDownLatch.countDown();
        });
        thread1.start();
        countDownLatch.await();
        System.out.println(" ----------------- ");
    }

等待時(shí)間中斷

        //程序計(jì)數(shù)器
        CountDownLatch countDownLatch = new CountDownLatch(1);
        Thread thread = Thread.currentThread();
        Thread thread1 = new Thread(() -> {
            try {
             Thread.sleep(10_000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        thread1.start();
        //2 中斷條件3
        countDownLatch.await(5, TimeUnit.SECONDS);
        System.out.println(" ----------------- ");
    }

就中斷條件而言: 當(dāng)前還可以父線(xiàn)程中斷

        //程序計(jì)數(shù)器
        Thread thread1 = new Thread(() -> {
            try {
             Thread.sleep(10_000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            // 中斷條件3
            thread.interrupt();
        });
        thread1.start();
        System.out.println(" ----------------- ");

用法四: 封裝結(jié)束完后通知事件

封裝結(jié)束完后通知事件 參考 CyclicBarrier 通知

public class CountDownLatchTest4 extends CountDownLatch {
    private Runnable runnable;
    public CountDownLatchTest4(int count, Runnable runnable) {
        super(count);
        this.runnable = runnable;
    }
    @Override
    public void countDown() {
        super.countDown();
        if (super.getCount()==0){
            runnable.run();
        }
    }
    public static void main(String[] args) throws InterruptedException {
        //程序計(jì)數(shù)器
        CountDownLatchTest4 countDownLatch = new CountDownLatchTest4(1,()->{
            System.out.println(" 計(jì)數(shù)結(jié)束 .... ");
        });
        Thread thread1 = new Thread(() -> {
            try {
                Thread.sleep(2_000);
                countDownLatch.countDown();
                System.out.println(" thread 1 do something ");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        Thread thread2 = new Thread(() -> {
            try {
                Thread.sleep(1_000);
                System.out.println(" thread 2 do something ");
                countDownLatch.countDown();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        thread1.start();
        thread2.start();
        countDownLatch.await();
        System.out.println("  -----------------  main 結(jié)束 ----------------- ");
    }
}

可以看到運(yùn)行結(jié)束,通知事件

自定義計(jì)數(shù)器

當(dāng)然我們也可以實(shí)現(xiàn)自己的計(jì)數(shù)器

/**
 * 自定義 CountDown 計(jì)數(shù)器
 */
public class CountDown {
    //計(jì)數(shù)器
    private int count = 0;
    private final int total;
    public CountDown(int total) {
        this.total = total;
    }
    public void countDown() {
        synchronized (this) {
            this.count++;
            //鎖住 ++ 通知其他線(xiàn)程
            this.notifyAll();
        }
    }
    public void aWait() throws InterruptedException {
        synchronized (this) {
            while (total != count) {
                //不等于 則 繼續(xù)等待
                this.wait();
            }
        }
    }
}

測(cè)試

        CountDown countDown = new CountDown( 5);
        System.out.println(" 準(zhǔn)備多線(xiàn)程處理任務(wù) ");
        IntStream.rangeClosed(1, 5).forEach(x -> {
            new Thread(() -> {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(" 線(xiàn)程開(kāi)始 -----  " + Thread.currentThread().getName());
                countDown.countDown();
            }, x + "").start();
        });
        try {
            countDown.aWait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(" 準(zhǔn)備多線(xiàn)程處理任務(wù) 結(jié)束 ");
        System.out.println(" ---------------------- ");
        System.out.println(" 結(jié)束 mian ---------- ");
    }

測(cè)試結(jié)果

最后

CountDownLatch 可以用來(lái)計(jì)數(shù),可以測(cè)試任務(wù)是否執(zhí)行結(jié)束

也可以用來(lái)停止一個(gè)線(xiàn)程,也可以用來(lái)線(xiàn)程運(yùn)行結(jié)束完后通知事件,彼此工作的線(xiàn)程互相獨(dú)立不關(guān)心。

到此這篇關(guān)于詳解Java中CountDownLatch的用法的文章就介紹到這了,更多相關(guān)Java CountDownLatch內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家

相關(guān)文章

最新評(píng)論