最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java中PriorityBlockingQueue的使用

 更新時(shí)間:2026年07月07日 09:15:44   作者:有夢(mèng)想的攻城獅  
PriorityBlockingQueue是Java并發(fā)包中的無(wú)界阻塞隊(duì)列,本文就來(lái)介紹一下Java中PriorityBlockingQueue的使用,感興趣的可以了解一下

一、核心特性與設(shè)計(jì)目標(biāo)

PriorityBlockingQueue 是 Java 并發(fā)包(java.util.concurrent)中基于 優(yōu)先級(jí)堆 實(shí)現(xiàn)的無(wú)界阻塞隊(duì)列,核心特性如下:

  1. 無(wú)界隊(duì)列:默認(rèn)容量為 Integer.MAX_VALUE,僅受內(nèi)存限制。
  2. 優(yōu)先級(jí)排序:元素按自然順序(實(shí)現(xiàn) Comparable)或自定義 Comparator 排序,優(yōu)先級(jí)最高者先出隊(duì)。
  3. 線程安全:通過(guò) ReentrantLock 和 Condition 實(shí)現(xiàn)并發(fā)控制。
  4. 阻塞特性:隊(duì)列為空時(shí),take() 阻塞;插入操作永不阻塞(無(wú)界特性)。
  5. 弱一致性迭代器:遍歷時(shí)可能看到部分更新,但不會(huì)拋出 ConcurrentModificationException。

二、內(nèi)部數(shù)據(jù)結(jié)構(gòu)與實(shí)現(xiàn)原理

1. 底層存儲(chǔ)結(jié)構(gòu)

數(shù)組實(shí)現(xiàn)的二叉堆:默認(rèn)最小堆(堆頂為最小元素),通過(guò)索引關(guān)系維護(hù)父子節(jié)點(diǎn):

// 父節(jié)點(diǎn)索引
parent(i) = (i-1) >>> 1  
// 左子節(jié)點(diǎn)索引
leftChild(i) = 2*i + 1  
// 右子節(jié)點(diǎn)索引
rightChild(i) = 2*i + 2

示例:數(shù)組 `` 對(duì)應(yīng)的堆結(jié)構(gòu)如上圖所示。

2. 核心字段

private transient Object[] queue;  // 存儲(chǔ)元素的數(shù)組
private transient int size;        // 當(dāng)前元素?cái)?shù)量
private final ReentrantLock lock;  // 主鎖
private final Condition notEmpty;  // 隊(duì)列非空條件
private transient Comparator<? super E> comparator;  // 比較器

3. 擴(kuò)容機(jī)制

  • 動(dòng)態(tài)擴(kuò)容:當(dāng)數(shù)組滿時(shí),按以下規(guī)則擴(kuò)容:
    • 小容量(<64):容量翻倍 + 2
    • 大容量:容量增長(zhǎng) 50%
    • 最大容量:Integer.MAX_VALUE - 8(防止內(nèi)存溢出)。
  • 無(wú)鎖擴(kuò)容:通過(guò) CAS 操作(allocationSpinLock)控制并發(fā)擴(kuò)容,避免線程阻塞。

三、核心方法與操作流程

1. 插入操作(offer())

public boolean offer(E e) {
    if (e == null) throw new NullPointerException();
    lock.lock();
    try {
        // 檢查是否需要擴(kuò)容
        if (size >= queue.length) grow();
        // 上浮操作維護(hù)堆性質(zhì)
        siftUp(size, e);
        size++;
        notEmpty.signal();  // 喚醒等待的消費(fèi)者
        return true;
    } finally {
        lock.unlock();
    }
}
  • 關(guān)鍵步驟:擴(kuò)容檢查 → 上?。?code>siftUp)調(diào)整堆結(jié)構(gòu) → 喚醒消費(fèi)者線程。

2. 出隊(duì)操作(take())

public E take() throws InterruptedException {
    lock.lockInterruptibly();
    try {
        while (size == 0) notEmpty.await();  // 隊(duì)列空時(shí)阻塞
        return dequeue();
    } finally {
        lock.unlock();
    }
}

private E dequeue() {
    E result = (E) queue;  // 取出堆頂元素
    E x = (E) queue@ref;  // 最后一個(gè)元素移到堆頂
    queue= null;  // 清除原堆頂
    if (size > 0) siftDown(0, x);  // 下沉操作維護(hù)堆性質(zhì)
    return result;
}
  • 關(guān)鍵步驟:阻塞等待 → 取出堆頂 → 下沉(siftDown)調(diào)整堆結(jié)構(gòu)。

3. 堆調(diào)整操作

  • 上?。╯iftUp):新元素插入后,與其父節(jié)點(diǎn)比較,若優(yōu)先級(jí)更高則交換,直到滿足堆性質(zhì)。
  • 下沉(siftDown):堆頂元素與子節(jié)點(diǎn)比較,若優(yōu)先級(jí)較低則交換,直到滿足堆性質(zhì)。

四、線程安全與性能優(yōu)化

1. 鎖機(jī)制

  • 單鎖設(shè)計(jì):所有修改操作(插入/刪除)共享同一把 ReentrantLock,簡(jiǎn)化實(shí)現(xiàn)但可能成為高并發(fā)瓶頸。
  • 條件變量:僅 notEmpty 用于消費(fèi)者等待,無(wú) notFull(因無(wú)界)。

2. 性能指標(biāo)

  • 插入時(shí)間復(fù)雜度:O(log n)(上浮操作)
  • 刪除時(shí)間復(fù)雜度:O(log n)(下沉操作)
  • 吞吐量:約 100,000-200,000 Ops/ms(8線程),低于 ConcurrentLinkedQueue。

五、適用場(chǎng)景與代碼示例

1. 典型場(chǎng)景

  • 任務(wù)調(diào)度系統(tǒng):高優(yōu)先級(jí)任務(wù)優(yōu)先執(zhí)行(如緊急訂單處理)。
  • 事件驅(qū)動(dòng)架構(gòu):按事件緊急程度處理(如實(shí)時(shí)監(jiān)控告警)。
  • 資源分配:VIP用戶優(yōu)先獲取資源(如數(shù)據(jù)庫(kù)連接池)。

2. 代碼示例

// 自定義任務(wù)類(降序優(yōu)先級(jí))
class Task implements Comparable<Task> {
    private int priority;
    public Task(int priority) { this.priority = priority; }
    @Override
    public int compareTo(Task o) {
        return Integer.compare(o.priority, this.priority);  // 降序排列
    }
}

// 使用示例
PriorityBlockingQueue<Task> queue = new PriorityBlockingQueue<>();
queue.put(new Task(3));  // 插入低優(yōu)先級(jí)任務(wù)
queue.put(new Task(1));  // 插入高優(yōu)先級(jí)任務(wù)
Task task = queue.take();  // 取出優(yōu)先級(jí)1的任務(wù)

六、與其他隊(duì)列的對(duì)比

特性PriorityBlockingQueueArrayBlockingQueueConcurrentLinkedQueue
容量無(wú)界有界無(wú)界
排序支持優(yōu)先級(jí)FIFO無(wú)序
鎖機(jī)制單鎖單鎖無(wú)鎖
適用場(chǎng)景優(yōu)先級(jí)調(diào)度有界緩沖高并發(fā)無(wú)序隊(duì)列

七、優(yōu)缺點(diǎn)總結(jié)

優(yōu)點(diǎn)

  1. 自動(dòng)排序:無(wú)需手動(dòng)管理優(yōu)先級(jí),簡(jiǎn)化代碼邏輯。
  2. 線程安全:內(nèi)置鎖機(jī)制保障并發(fā)安全。
  3. 無(wú)界設(shè)計(jì):避免生產(chǎn)者線程因隊(duì)列滿而阻塞。

缺點(diǎn)

  1. 內(nèi)存風(fēng)險(xiǎn):無(wú)界可能導(dǎo)致內(nèi)存溢出,需監(jiān)控隊(duì)列大小。
  2. 單鎖瓶頸:高并發(fā)下性能受限,可考慮分片隊(duì)列優(yōu)化。
  3. 不支持延遲:需結(jié)合 ScheduledThreadPoolExecutor 實(shí)現(xiàn)延遲任務(wù)。

八、源碼設(shè)計(jì)亮點(diǎn)

  1. 堆化操作:通過(guò) heapify() 方法將普通數(shù)組快速轉(zhuǎn)換為堆結(jié)構(gòu)。
  2. 自旋鎖擴(kuò)容:使用 allocationSpinLock 減少擴(kuò)容時(shí)的線程阻塞。
  3. 弱一致性迭代:迭代器遍歷時(shí)允許并發(fā)修改,避免 ConcurrentModificationException

九、最佳實(shí)踐

  1. 合理設(shè)置初始容量:根據(jù)預(yù)估數(shù)據(jù)量減少擴(kuò)容次數(shù)。
  2. 自定義比較器:明確優(yōu)先級(jí)規(guī)則,避免自然排序歧義。
  3. 監(jiān)控隊(duì)列狀態(tài):通過(guò) size()remainingCapacity() 預(yù)防內(nèi)存溢出。
  4. 結(jié)合線程池使用:與 ThreadPoolExecutor 集成實(shí)現(xiàn)優(yōu)先級(jí)任務(wù)調(diào)度。

通過(guò)合理利用 PriorityBlockingQueue,可高效實(shí)現(xiàn)基于優(yōu)先級(jí)的并發(fā)任務(wù)處理,但需注意其無(wú)界特性帶來(lái)的內(nèi)存風(fēng)險(xiǎn)。在需要嚴(yán)格容量控制的場(chǎng)景中,可考慮使用 ArrayBlockingQueue 或分片策略。

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

相關(guān)文章

  • Retrofit+RxJava實(shí)現(xiàn)帶進(jìn)度下載文件

    Retrofit+RxJava實(shí)現(xiàn)帶進(jìn)度下載文件

    這篇文章主要為大家詳細(xì)介紹了Retrofit+RxJava實(shí)現(xiàn)帶進(jìn)度下載文件,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-05-05
  • Java編程中的一些常見問題匯總

    Java編程中的一些常見問題匯總

    這篇文章主要介紹了Java編程中的一些常見問題匯總,本文總結(jié)的都是一些Java代碼中比較典型的錯(cuò)誤,需要的朋友可以參考下
    2014-09-09
  • String轉(zhuǎn)double失去精度問題及解決

    String轉(zhuǎn)double失去精度問題及解決

    這篇文章主要介紹了關(guān)于String轉(zhuǎn)double失去精度問題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • Maven依賴中scope的含義

    Maven依賴中scope的含義

    本文主要介紹了Maven依賴中scope的含義,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • Java中如何自定義一個(gè)類加載器

    Java中如何自定義一個(gè)類加載器

    這篇文章主要介紹了Java中如何自定義一個(gè)類加載器,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • Java中Comparator與Comparable排序的區(qū)別詳解

    Java中Comparator與Comparable排序的區(qū)別詳解

    這篇文章主要介紹了Java中Comparator與Comparable排序的區(qū)別詳解,如果你有一個(gè)類,希望支持同類型的自定義比較策略,可以實(shí)現(xiàn)接口Comparable,如果某個(gè)類,沒有實(shí)現(xiàn)Comparable,但是又希望對(duì)它進(jìn)行比較,則可以自定義一個(gè)Comparator,需要的朋友可以參考下
    2024-01-01
  • Java雪花算法的原理和實(shí)現(xiàn)方法

    Java雪花算法的原理和實(shí)現(xiàn)方法

    這篇文章主要介紹了Java雪花算法的原理和實(shí)現(xiàn)方法,雪花算法是一種分布式唯一ID生成算法,可以生成全局唯一的ID標(biāo)識(shí)符,就像自然界中雪花一般沒有相同的雪花,下面將詳細(xì)介紹,感興趣的可以學(xué)習(xí)一下
    2023-10-10
  • Java局部變量線程安全原理分析

    Java局部變量線程安全原理分析

    這篇文章主要介紹了Java局部變量線程安全原理分析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-10-10
  • Java?超詳細(xì)講解類的定義方式和對(duì)象的實(shí)例化

    Java?超詳細(xì)講解類的定義方式和對(duì)象的實(shí)例化

    Java是一門純面向?qū)ο蟮恼Z(yǔ)言(Object?Oriented?Program,繼承OOP),在面對(duì)對(duì)象的世界里面,一切皆為對(duì)象。面向?qū)ο笫墙鉀Q問題的一種思想,主要依靠對(duì)象之間的交互完成一件事情
    2022-03-03
  • Spring IOC與DI核心深入理解

    Spring IOC與DI核心深入理解

    IOC也是Spring的核心之一了,之前學(xué)的時(shí)候是采用xml配置文件的方式去實(shí)現(xiàn)的,后來(lái)其中也多少穿插了幾個(gè)注解,但是沒有說(shuō)完全采用注解實(shí)現(xiàn)。那么這篇文章就和大家分享一下,全部采用注解來(lái)實(shí)現(xiàn)IOC+DI
    2023-02-02

最新評(píng)論

平凉市| 呼伦贝尔市| 肥乡县| 青川县| 慈溪市| 休宁县| 彰化县| 天水市| 姚安县| 奈曼旗| 泾源县| 闽清县| 平罗县| 芜湖县| 孙吴县| 衡阳县| 东兰县| 五常市| 兰溪市| 永丰县| 紫云| 鹤壁市| 宁乡县| 武宣县| 浦北县| 广宗县| 白玉县| 郴州市| 开封市| 南康市| 古浪县| 巴彦淖尔市| 台南县| 佛山市| 辉县市| 安徽省| 茶陵县| 双辽市| 高雄市| 高安市| 临夏县|