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

Java 阻塞隊列的7種類型小結

 更新時間:2025年07月09日 10:16:24   作者:@zcc@  
Java中的阻塞隊列是線程安全的隊列結構,包括ArrayBlockingQueue、LinkedBlockingQueue、PriorityBlockingQueue、DelayQueue、SynchronousQueue、LinkedTransferQueue和LinkedBl,下面就來具體介紹一下,感興趣的可以了解一下

在 Java 中,阻塞隊列(BlockingQueue) 是一種線程安全的隊列結構,用于實現(xiàn)生產者-消費者模式。它的核心特性是在隊列為空時阻塞消費者線程,在隊列滿時阻塞生產者線程,從而自動協(xié)調線程之間的協(xié)作。

阻塞隊列的核心特性

  1. 線程安全:所有操作(如 put、take)都是線程安全的。
  2. 阻塞操作
    • 隊列滿時:生產者線程阻塞(等待消費者消費)。
    • 隊列空時:消費者線程阻塞(等待生產者生產)。
  3. 超時控制:支持帶超時時間的操作(如 offer(timeout, unit)poll(timeout, unit))。
  4. 公平策略:部分實現(xiàn)(如 ArrayBlockingQueue)支持公平鎖,防止線程饑餓。

Java 中的 7 種阻塞隊列

以下是 Java 提供的 7 種阻塞隊列及其特點和適用場景:

1. ArrayBlockingQueue(有界隊列)

  • 特點
    • 基于數(shù)組實現(xiàn),容量固定(初始化時指定)。
    • 支持公平鎖(默認非公平鎖)。
  • 適用場景
    • 需要嚴格限制隊列容量的場景(如任務量可控的線程池)。
  • 示例代碼
    BlockingQueue<String> queue = new ArrayBlockingQueue<>(3);
    queue.put("A"); // 隊列滿時阻塞
    String task = queue.take(); // 隊列空時阻塞
    

2. LinkedBlockingQueue(有界/無界隊列)

  • 特點
    • 基于鏈表實現(xiàn),默認容量為 Integer.MAX_VALUE(可視為無界)。
    • 入隊和出隊使用獨立鎖(putLocktakeLock),提高并發(fā)性能。
  • 適用場景
    • 任務量不可預測的高吞吐量場景(如線程池默認隊列)。
  • 示例代碼
    BlockingQueue<Integer> queue = new LinkedBlockingQueue<>(100); // 指定容量
    queue.put(1); // 隊列滿時阻塞
    Integer task = queue.take(); // 隊列空時阻塞
    

3. PriorityBlockingQueue(無界優(yōu)先級隊列)

  • 特點
    • 無界隊列,基于優(yōu)先級堆實現(xiàn)。
    • 元素必須實現(xiàn) Comparable 接口或提供比較器。
  • 適用場景
    • 需要按優(yōu)先級處理任務(如緊急任務優(yōu)先)。
  • 示例代碼
    BlockingQueue<PriorityTask> queue = new PriorityBlockingQueue<>();
    queue.put(new PriorityTask(1)); // 任務優(yōu)先級由 compareTo() 決定
    PriorityTask task = queue.take();
    

4. DelayQueue(延遲隊列)

  • 特點
    • 無界隊列,元素必須實現(xiàn) Delayed 接口。
    • 只有在延遲時間到達后,任務才能被取出。
  • 適用場景
    • 定時任務(如緩存過期、訂單超時)。
  • 示例代碼
    DelayQueue<DelayedTask> queue = new DelayQueue<>();
    queue.put(new DelayedTask(5000)); // 5 秒后可用
    DelayedTask task = queue.take(); // 等待任務延遲時間到期
    

5. SynchronousQueue(同步隊列)

  • 特點
    • 無容量隊列,每個插入操作必須等待一個對應的移除操作。
    • 生產者和消費者直接傳遞數(shù)據(jù)。
  • 適用場景
    • 高吞吐量的短任務場景(如 newCachedThreadPool)。
  • 示例代碼
    BlockingQueue<String> queue = new SynchronousQueue<>();
    queue.put("X"); // 阻塞直到有消費者調用 take()
    String task = queue.take(); // 阻塞直到有生產者調用 put()
    

6. LinkedTransferQueue(無界隊列)

  • 特點
    • 支持“預占模式”(生產者和消費者直接交互)。
    • 高性能的無界隊列。
  • 適用場景
    • 需要高效傳遞任務的場景(如快速響應的系統(tǒng))。
  • 示例代碼
    BlockingQueue<Integer> queue = new LinkedTransferQueue<>();
    queue.put(100); // 直接傳遞給消費者
    Integer task = queue.take(); // 立即獲取任務
    

7. LinkedBlockingDeque(雙向阻塞隊列)

  • 特點
    • 雙端隊列,支持從兩端插入/移除元素。
    • 可作為有界或無界隊列。
  • 適用場景
    • 工作竊取算法(如 ForkJoinPool)。
  • 示例代碼
    BlockingQueue<String> queue = new LinkedBlockingDeque<>(100);
    queue.put("A"); // 從尾部插入
    String task = queue.take(); // 從頭部移除
    

阻塞隊列的核心方法

方法行為拋出異常返回布爾值阻塞超時阻塞
add(E e)插入元素隊列滿時拋異常-
offer(E e)插入元素隊列滿時返回 false-
offer(E e, long timeout, TimeUnit unit)插入元素超時后返回 false-
put(E e)插入元素--
remove()移除元素隊列空時拋異常-
poll()移除元素隊列空時返回 null-
poll(long timeout, TimeUnit unit)移除元素超時后返回 null-
take()移除元素--

如何選擇阻塞隊列?

  1. 有界 vs 無界:
    • 有界隊列(如 ArrayBlockingQueue):防止內存溢出,需合理設置容量。
    • 無界隊列(如 LinkedBlockingQueue):可能導致任務堆積,需結合拒絕策略使用。
  2. 優(yōu)先級需求:
    • 使用 PriorityBlockingQueue 實現(xiàn)優(yōu)先級排序。
  3. 延遲任務:
    • 使用 DelayQueue 實現(xiàn)定時或延遲執(zhí)行。
  4. 高性能場景:
    • SynchronousQueue 適合高吞吐量的短任務。
    • LinkedTransferQueue 適合快速傳遞任務的場景。

示例:使用阻塞隊列實現(xiàn)生產者-消費者模型

import java.util.concurrent.*;

public class ProducerConsumerExample {
    public static void main(String[] args) {
        BlockingQueue<String> queue = new LinkedBlockingQueue<>(10);

        // 生產者線程
        Thread producer = new Thread(() -> {
            try {
                for (int i = 0; i < 10; i++) {
                    String task = "Task-" + i;
                    queue.put(task); // 隊列滿時阻塞
                    System.out.println("Produced: " + task);
                    Thread.sleep(100);
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        });

        // 消費者線程
        Thread consumer = new Thread(() -> {
            try {
                while (true) {
                    String task = queue.take(); // 隊列空時阻塞
                    System.out.println("Consumed: " + task);
                    Thread.sleep(200);
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        });

        producer.start();
        consumer.start();
    }
}

注意事項

  1. 避免內存泄漏
    • 使用無界隊列時,需結合線程池的拒絕策略(如 CallerRunsPolicy)。
  2. 公平性
    • ArrayBlockingQueue 支持公平鎖(構造函數(shù)傳入 true)。
  3. 線程中斷
    • 阻塞操作(如 put/take)會響應中斷,需捕獲 InterruptedException。

通過合理選擇阻塞隊列類型,可以高效地實現(xiàn)線程間的協(xié)作,解決生產者-消費者問題。

到此這篇關于Java 阻塞隊列的7種類型小結的文章就介紹到這了,更多相關Java 阻塞隊列內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • springboot整合mybatis分頁攔截器的問題小結

    springboot整合mybatis分頁攔截器的問題小結

    springboot整合mybatis分頁攔截器,分頁攔截實際上就是獲取sql后將sql拼接limit,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2021-07-07
  • java網(wǎng)上圖書商城(2)Category模塊

    java網(wǎng)上圖書商城(2)Category模塊

    這篇文章主要介紹了java網(wǎng)上圖書商城,Category模塊,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-12-12
  • mybatis if test條件判斷語句中的判斷問題分析

    mybatis if test條件判斷語句中的判斷問題分析

    這篇文章主要介紹了mybatis if test條件判斷語句中的判斷問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • Java預覽PDF時的文件名稱問題及解決

    Java預覽PDF時的文件名稱問題及解決

    這篇文章主要介紹了Java預覽PDF時的文件名稱問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • 多模塊的springboot項目發(fā)布指定模塊的腳本方式

    多模塊的springboot項目發(fā)布指定模塊的腳本方式

    該文章主要介紹了如何在多模塊的SpringBoot項目中發(fā)布指定模塊的腳本,作者原先的腳本會清理并編譯所有模塊,導致發(fā)布時間過長,通過簡化腳本,只使用`mvn clean install`命令,可以快速發(fā)布指定模塊及其依賴的模塊
    2025-01-01
  • 學習Java多線程之同步

    學習Java多線程之同步

    這篇文章主要為大家詳細介紹了Java多線程之同步,感興趣的小伙伴們可以參考一下
    2016-02-02
  • Resilience4J通過yml設置circuitBreaker的方法

    Resilience4J通過yml設置circuitBreaker的方法

    Resilience4j是一個輕量級、易于使用的容錯庫,其靈感來自Netflix Hystrix,但專為Java 8和函數(shù)式編程設計,這篇文章主要介紹了Resilience4J通過yml設置circuitBreaker的方法,需要的朋友可以參考下
    2022-10-10
  • java 并發(fā)中的原子性與可視性實例詳解

    java 并發(fā)中的原子性與可視性實例詳解

    這篇文章主要介紹了java 并發(fā)中的原子性與可視性實例詳解的相關資料,原子性是說一個操作是否可分割??梢娦允钦f操作結果其他線程是否可見。需要的朋友可以參考下
    2017-07-07
  • MybatisX中xml映射文件中命名空間爆紅的解決

    MybatisX中xml映射文件中命名空間爆紅的解決

    本文主要介紹了MybatisX中xml映射文件中命名空間爆紅的解決,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-06-06
  • Spring?AOP中三種增強方式的示例詳解

    Spring?AOP中三種增強方式的示例詳解

    AOP?(Aspect?Orient?Programming),直譯過來就是?面向切面編程。AOP?是一種編程思想,是面向對象編程(OOP)的一種補充。本文為大家介紹了Spring?AOP中三種增強方式,感興趣的可以了解一下
    2022-07-07

最新評論