欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java中的CyclicBarrier、CountDownLatch和Semaphore的具體使用

 更新時(shí)間:2024年05月28日 08:34:03   作者:逆流的小魚(yú)168  
本文主要介紹了Java中的CyclicBarrier、CountDownLatch和Semaphore的具體使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

1.CountDownLatch

1.1 介紹和用途

CountDownLatch 是一個(gè)同步助手類,在完成一組正在其他線程中執(zhí)行的操作之前,它允許一個(gè)或多個(gè)線程一直等待。

1.2 工作原理

它通過(guò)一個(gè)計(jì)數(shù)器來(lái)實(shí)現(xiàn),我們初始化 CountDownLatch 對(duì)象時(shí)指定計(jì)數(shù)器的值,每當(dāng)一個(gè)指定的操作執(zhí)行完成后,計(jì)數(shù)值就減一。當(dāng)計(jì)數(shù)值達(dá)到零時(shí),它表示所有需要等待的操作都完成了,此時(shí)阻塞在 CountDownLatch 上的線程就可以恢復(fù)執(zhí)行任務(wù)。

1.3 使用場(chǎng)景和示例代碼

CountDownLatch 經(jīng)常用于確保某些操作在繼續(xù)執(zhí)行應(yīng)用程序剩余部分之前完成,例如,服務(wù)器的服務(wù)依賴在接受請(qǐng)求前必須初始化完成。

import java.util.concurrent.CountDownLatch;
public class ServiceLoader {
    // 初始計(jì)數(shù)器為3,表示需要等待3個(gè)服務(wù)加載
    private static final CountDownLatch latch = new CountDownLatch(3);
    public static void main(String[] args) throws InterruptedException {
        // 啟動(dòng)服務(wù)加載線程
        new Thread(new Service("Service 1", latch)).start();
        new Thread(new Service("Service 2", latch)).start();
        new Thread(new Service("Service 3", latch)).start();
        // 主線程等待服務(wù)加載完成
        latch.await();
        System.out.println("所有服務(wù)已加載完成,服務(wù)可以開(kāi)始接收請(qǐng)求...");
    }
    static class Service implements Runnable {
        private final String name;
        private final CountDownLatch latch;
        public Service(String name, CountDownLatch latch) {
            this.name = name;
            this.latch = latch;
        }
        @Override
        public void run() {
            try {
                // 模擬服務(wù)加載耗時(shí)操作
                Thread.sleep((long) (Math.random() * 1000));
                System.out.println(name + " 服務(wù)加載完成.");
                // 服務(wù)加載完成后,計(jì)數(shù)器減一
                latch.countDown();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }
}

1.4 注意事項(xiàng)和最佳實(shí)踐

CountDownLatch 的計(jì)數(shù)器無(wú)法被重置,如果需要一個(gè)能夠重置計(jì)數(shù)的版本,可以考慮使用 CyclicBarrier。在使用時(shí)還需注意異常處理,避免由于異常造成的線程永遠(yuǎn)等待的情況。

2.CyclicBarrier

2.1 介紹和用途

CyclicBarrier 是一個(gè)同步助手類,它允許一組線程互相等待,直到所有線程都到達(dá)一個(gè)公共的屏障點(diǎn)(Barrier Point)后才繼續(xù)執(zhí)行。

2.2 工作原理

CyclicBarrier 通過(guò)內(nèi)部計(jì)數(shù)器來(lái)跟蹤到達(dá)屏障點(diǎn)的線程數(shù)。當(dāng)線程到達(dá)屏障點(diǎn)時(shí),它調(diào)用 await() 方法,并阻塞直到指定數(shù)量的線程都到達(dá)了屏障點(diǎn)。此時(shí),屏障打開(kāi),所有阻塞的線程將繼續(xù)執(zhí)行。不同于 CountDownLatch,CyclicBarrier 是可重用的。

2.3 使用場(chǎng)景和示例代碼

CyclicBarrier 常用于多線程計(jì)算數(shù)據(jù)的場(chǎng)景,需要等到全部線程完成計(jì)算,才能進(jìn)行下一步的處理。

import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.BrokenBarrierException;
public class DataProcessor {
    private static final int NUMBER_OF_THREADS = 3;
    private static CyclicBarrier barrier = new CyclicBarrier(NUMBER_OF_THREADS, 
        new Runnable() {
            @Override
            public void run() {
                // 當(dāng)所有線程到達(dá)屏障點(diǎn)時(shí)執(zhí)行
                System.out.println("所有計(jì)算完成,進(jìn)行數(shù)據(jù)合并...");
            }
        });
    public static void main(String[] args) {
        for(int i = 0; i < NUMBER_OF_THREADS; i++) {
            new Thread(new Worker(i)).start();
        }
    }
    static class Worker implements Runnable {
        private int id;
        public Worker(int id) {
            this.id = id;
        }
        @Override
        public void run() {
            try {
                // 模擬數(shù)據(jù)處理
                System.out.println("線程 #" + id + " 正在處理數(shù)據(jù)...");
                Thread.sleep((long) (Math.random() * 1000));
                System.out.println("線程 #" + id + " 數(shù)據(jù)處理完成,等待其他線程...");
                // 等待其他線程都執(zhí)行到這個(gè)點(diǎn)
                barrier.await();
                System.out.println("線程 #" + id + " 繼續(xù)后續(xù)操作...");
            } catch (InterruptedException | BrokenBarrierException e) {
                e.printStackTrace();
            }
        }
    }
}

2.4 與CountDownLatch的比較

與 CountDownLatch 相比,CyclicBarrier 可以在所有等待線程都被釋放后重置計(jì)數(shù)器,而 CountDownLatch 不能重置。

2.5 注意事項(xiàng)和最佳實(shí)踐

使用 CyclicBarrier 時(shí)需要注意,如果任何線程在等待過(guò)程中因?yàn)橹袛嗷蛘叱瑫r(shí)而提前離開(kāi)屏障點(diǎn), 或者等待線程的數(shù)目永遠(yuǎn)不足以達(dá)到屏障點(diǎn),這將導(dǎo)致所有在屏障點(diǎn)等待的線程拋出 BrokenBarrierException。因此,在使用時(shí)需要妥善處理這些可能的異常場(chǎng)景。
為了避免這種情形,可以在 await 方法中設(shè)置一個(gè)超時(shí)時(shí)間,并適當(dāng)處理 TimeoutException。同時(shí),可以通過(guò) isBroken 方法檢查屏障點(diǎn)的狀態(tài),以便在必要時(shí)對(duì)線程進(jìn)行重新安排或者重置屏障點(diǎn)。
除此之外,設(shè)計(jì)上建議只在所有參與線程要完成的任務(wù)確實(shí)需要互相等待時(shí)才使用 CyclicBarrier,在任務(wù)獨(dú)立的情況下使用 CountDownLatch 會(huì)更為合適。

3.Semaphore

3.1 介紹和用途

Semaphore(信號(hào)量)是一種基于計(jì)數(shù)的同步機(jī)制,它可以用來(lái)控制同時(shí)訪問(wèn)特定資源的線程數(shù)量,是實(shí)現(xiàn)資源池或者限制容量的一個(gè)有力工具。

3.2 工作原理

Semaphore 管理一組許可證(permits),線程可以通過(guò) acquire() 方法獲取許可證,如果 Semaphore 內(nèi)部計(jì)數(shù)為零,表示沒(méi)有許可證可用,線程將會(huì)阻塞直到有許可證被釋放。相反,線程完成任務(wù)后,可以通過(guò) release() 方法釋放許可證,并將其返回給信號(hào)量。

3.3 使用場(chǎng)景和示例代碼

Semaphore 通常用于對(duì)資源池進(jìn)行控制,比如數(shù)據(jù)庫(kù)連接池,限制同時(shí)訪問(wèn)的連接數(shù),或者在限流控制中限制同時(shí)執(zhí)行的線程數(shù)量。

import java.util.concurrent.Semaphore;
public class ResourcePool {
    private static final int MAX_AVAILABLE = 5;
    private final Semaphore available = new Semaphore(MAX_AVAILABLE, true);
    public Object getItem() throws InterruptedException {
        available.acquire();
        try {
            // 模擬獲取資源的操作
            return getNextAvailableItem();
        } finally {
            // 保證在資源使用后一定會(huì)釋放許可證
            available.release();
        }
    }
    // 此處省略了資源管理的其他邏輯...
    public static void main(String[] args) {
        final ResourcePool pool = new ResourcePool();
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                try {
                    Object item = pool.getItem();
                    // 模擬使用資源
                    System.out.println(Thread.currentThread().getName() + " 獲取了資源");
                    Thread.sleep((long) (Math.random() * 1000));
                    // 假設(shè)這里是使用資源完成后的操作
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }).start();
        }
    }
    // 此處省略了getNextAvailableItem方法的實(shí)現(xiàn),它應(yīng)該負(fù)責(zé)分配資源
}

在以上代碼示例中,我們?cè)O(shè)置了最大并發(fā)數(shù),并通過(guò) Semaphore 來(lái)限制訪問(wèn)資源的線程數(shù)。當(dāng)所有許可證都被占用時(shí),后來(lái)的線程將會(huì)等待直到有線程釋放許可證。

3.4 和其他同步工具的比較

相比其他同步工具,Semaphore 提供了對(duì)資源的并發(fā)訪問(wèn)控制,而 CountDownLatch 和 CyclicBarrier 更側(cè)重于線程的協(xié)調(diào)和等待。

3.5 注意事項(xiàng)和最佳實(shí)踐

使用 Semaphore 時(shí),要確保在資源使用后,準(zhǔn)確無(wú)誤地釋放許可證,否則可能會(huì)導(dǎo)致其他線程永久等待。在實(shí)際應(yīng)用中,尤其在復(fù)雜的業(yè)務(wù)邏輯里,通常建議使用 try-finally` 語(yǔ)句確保許可證的正確釋放。
同時(shí),合理配置許可證的數(shù)量對(duì)于系統(tǒng)的穩(wěn)定性和性能至關(guān)重要。對(duì)于資源競(jìng)爭(zhēng)激烈的場(chǎng)景,設(shè)置過(guò)少的許可證可能會(huì)導(dǎo)致系統(tǒng)響應(yīng)時(shí)間增長(zhǎng);反之,設(shè)置過(guò)多的許可證則可能會(huì)超出系統(tǒng)資源的實(shí)際承載能力,造成資源的浪費(fèi)或系統(tǒng)崩潰。

總結(jié)

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

相關(guān)文章

  • 解決MyEclipse中的Building workspace問(wèn)題的三個(gè)方法

    解決MyEclipse中的Building workspace問(wèn)題的三個(gè)方法

    這篇文章主要介紹了解決MyEclipse中的Building workspace問(wèn)題的三個(gè)方法,需要的朋友可以參考下
    2015-11-11
  • Java Servlet簡(jiǎn)單實(shí)例分享(文件上傳下載demo)

    Java Servlet簡(jiǎn)單實(shí)例分享(文件上傳下載demo)

    下面小編就為大家?guī)?lái)一篇Java Servlet簡(jiǎn)單實(shí)例分享(文件上傳下載demo)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-05-05
  • Zookeeper如何實(shí)現(xiàn)分布式服務(wù)配置中心詳解

    Zookeeper如何實(shí)現(xiàn)分布式服務(wù)配置中心詳解

    Zookeeper在實(shí)際使用場(chǎng)景很多,比如配置中心,分布式鎖,注冊(cè)中心等,下面這篇文章主要給大家介紹了關(guān)于Zookeeper如何實(shí)現(xiàn)分布式服務(wù)配置中心的相關(guān)資料,需要的朋友可以參考下
    2021-11-11
  • java鍵盤錄入的方法舉例詳解

    java鍵盤錄入的方法舉例詳解

    這篇文章主要給大家介紹了關(guān)于java鍵盤錄入的相關(guān)資料,我們?cè)趯?xiě)程序的時(shí)候,數(shù)據(jù)值都是固定的,但是實(shí)際開(kāi)發(fā)中,數(shù)據(jù)值肯定是變化的,所以,把數(shù)據(jù)改進(jìn)為鍵盤錄入,提高程序的靈活性,需要的朋友可以參考下
    2023-10-10
  • springboot集成mybatisplus實(shí)例詳解

    springboot集成mybatisplus實(shí)例詳解

    這篇文章主要介紹了springboot集成mybatisplus實(shí)例詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-09-09
  • Java中實(shí)現(xiàn)List分隔成子List詳解

    Java中實(shí)現(xiàn)List分隔成子List詳解

    大家好,本篇文章主要講的是Java中實(shí)現(xiàn)List分隔成子List詳解,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下
    2022-01-01
  • 一篇文章徹底理解SpringIOC、DI

    一篇文章徹底理解SpringIOC、DI

    這篇文章主要給大家介紹了關(guān)于對(duì)SpringIOC、DI的理解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • mybatis-plus雪花算法生成Id使用詳解

    mybatis-plus雪花算法生成Id使用詳解

    本文主要介紹了mybatis-plus雪花算法生成Id使用詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • Java消息隊(duì)列RabbitMQ之消息模式詳解

    Java消息隊(duì)列RabbitMQ之消息模式詳解

    這篇文章主要介紹了Java消息隊(duì)列RabbitMQ之消息模式詳解,RabbitMQ提供了一種qos(服務(wù)質(zhì)量保證)功能,即在非自動(dòng)確認(rèn)消息的前提下,如果一定數(shù)目的消息(通過(guò)基于Consumer或者Channel設(shè)置Qos的值)未被確認(rèn)前,不進(jìn)行消費(fèi)新的消息,需要的朋友可以參考下
    2023-07-07
  • mybatis中實(shí)現(xiàn)讓返回值與bean中字段相匹配

    mybatis中實(shí)現(xiàn)讓返回值與bean中字段相匹配

    這篇文章主要介紹了mybatis中實(shí)現(xiàn)讓返回值與bean中字段相匹配,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-10-10

最新評(píng)論