首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 數據結構精講:隊列原理、循環隊列實現與生產級替代方案

     編輯:Java 相關知識

隊列核心定義

隊列 是先進先出(FIFO, First In First Out)的線性表。僅允許在隊尾插入、隊頭刪除。生活類比:排隊買票、打印任務隊列、消息中介軟體。

順序隊列的「假溢出」問題

陣列實現中,front 和 rear 只增不減,導致邏輯上還有空閒位置卻無法入隊。解決方案:循環隊列——下標取模 capacity 實現首尾相接。

循環隊列關鍵條件

狀態條件說明
空front == rear初始狀態、出隊後
滿(rear + 1) % capacity == front犧牲一個槽位區分空/滿
元素個數(rear - front + capacity) % capacity

循環隊列完整實現

public class CircularQueue<E> {
    private final E[] elements;
    private int front = 0, rear = 0;

    @SuppressWarnings("unchecked")
    public CircularQueue(int capacity) {
        elements = (E[]) new Object[capacity + 1]; // +1 區分空滿
    }

    public boolean offer(E e) {
        if (isFull()) return false;
        elements[rear] = e;
        rear = (rear + 1) % elements.length;
        return true;
    }

    public E poll() {
        if (isEmpty()) return null;
        E e = elements[front];
        elements[front] = null; // GC 友好
        front = (front + 1) % elements.length;
        return e;
    }

    public E peek() { return isEmpty() ? null : elements[front]; }
    public boolean isEmpty() { return front == rear; }
    public boolean isFull() { return (rear + 1) % elements.length == front; }
    public int size() { return (rear - front + elements.length) % elements.length; }
}

JDK 生產級隊列族譜

介面/類特點適用場景
ArrayDeque雙端隊列、陣列、無容量上限、非線程安全單線程棧/隊列、高效能
LinkedList雙向鏈表、實現 Deque、非線程安全頻繁頭尾操作、記憶體不連續
PriorityQueue優先隊列、堆實現、非線程安全任務調度、Top-K 問題
BlockingQueue阻塞隊列介面、多線程安全生產者-消費者模型
LinkedBlockingQueue鏈表、可選容量上限高併發、無界/有界緩衝
ArrayBlockingQueue陣列、固定容量、公平鎖可選固定緩衝區、低延遲
ConcurrentLinkedQueue無鎖 CAS、非阻塞極高併發、最終一致性
DelayQueue延遲隊列、元素實現 Delayed定時任務、緩存過期清理

選型決策樹

  1. 單線程、高效能 → ArrayDeque
  2. 多線程、需阻塞等待 → LinkedBlockingQueue(無界)或 ArrayBlockingQueue(有界)
  3. 多線程、非阻塞、高併發 → ConcurrentLinkedQueue
  4. 需按優先級處理 → PriorityQueue(單線程)或 PriorityBlockingQueue(多線程)
  5. 需延遲執行 → DelayQueue

經典應用:生產者-消費者模板

BlockingQueue<Task> queue = new LinkedBlockingQueue<>(100);

// 生產者
new Thread(() -> {
    while (true) {
        try { queue.put(produceTask()); } 
        catch (InterruptedException e) { break; }
    }
}).start();

// 消費者
new Thread(() -> {
    while (true) {
        try { Task t = queue.take(); consume(t); } 
        catch (InterruptedException e) { break; }
    }
}).start();

避坑指南

  • offer/poll 不拋異常、返回 boolean/null,add/remove 會拋異常,根據業務選擇;
  • 有界隊列必須處理滿/空情況,否則生產者/消費者線程會無限阻塞;
  • 避免在持有鎖時執行耗時操作,導致吞吐崩潰;
  • 隊列元素建議不可變,避免併發修改導致不一致。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved