Java常用队列并发队列实现与应用场景详解

Java常用队列并发队列实现与应用场景详解

在Java中,Queue接口是java.util包的一部分,继承自Collection接口,用于在处理前保存元素。它遵循FIFO(先进先出)原则,但优先级队列和LIFO队列除外。以下是关于Java队列的超全面介绍:

1. Queue接口的基本方法

方法

描述

异常情况(失败时)

返回特殊值(失败时)

add(e)

添加元素到队列尾部

IllegalStateException

false

offer(e)

尝试添加元素(更适合有容量限制的队列)

-

false

remove()

移除并返回队首元素

NoSuchElementException

-

poll()

移除并返回队首元素(队列为空时返回null)

-

null

element()

返回队首元素(不移除)

NoSuchElementException

-

peek()

返回队首元素(不移除,队列为空时返回null)

-

null

2. 常用实现类

2.1 LinkedList

特点:实现了Queue和Deque接口,支持双向队列操作。

适用场景:频繁插入/删除元素的场景。

Queue queue = new LinkedList<>();

queue.offer("A");

queue.offer("B");

System.out.println(queue.poll()); // 输出: A

2.2 PriorityQueue

特点:基于优先级堆实现,元素按自然顺序或指定比较器排序。

注意:不允许null元素,非线程安全。

Queue priorityQueue = new PriorityQueue<>();

priorityQueue.offer(3);

priorityQueue.offer(1);

System.out.println(priorityQueue.poll()); // 输出: 1(最小元素优先)

2.3 ArrayDeque

特点:动态数组实现的双端队列,不允许null元素。

优势:无容量限制,比LinkedList在队列操作上更高效。

Deque deque = new ArrayDeque<>();

deque.offerFirst("A");

deque.offerLast("B");

System.out.println(deque.pollLast()); // 输出: B

2.4 ConcurrentLinkedQueue

特点:基于链表的无界线程安全队列,采用CAS(Compare-and-Swap)操作。

适用场景:高并发环境。

Queue concurrentQueue = new ConcurrentLinkedQueue<>();

concurrentQueue.offer("Task1");

concurrentQueue.poll(); // 线程安全操作

2.5 BlockingQueue接口及实现类

用于线程间通信,支持阻塞操作(如put()和take())。

ArrayBlockingQueue:有界数组实现的阻塞队列。

LinkedBlockingQueue:可选有界的链表阻塞队列。

PriorityBlockingQueue:支持优先级的无界阻塞队列。

DelayQueue:延迟元素的无界阻塞队列,元素必须实现Delayed接口。

BlockingQueue blockingQueue = new ArrayBlockingQueue<>(10);

blockingQueue.put("Item"); // 队列满时阻塞

String item = blockingQueue.take(); // 队列空时阻塞

3. 双端队列(Deque)

Deque接口继承自Queue,支持两端元素插入和删除。

常用方法:

addFirst(e)/offerFirst(e)

addLast(e)/offerLast(e)

removeFirst()/pollFirst()

removeLast()/pollLast()

getFirst()/peekFirst()

getLast()/peekLast()

Deque deque = new ArrayDeque<>();

deque.push(1); // 等价于 addFirst()

deque.push(2);

System.out.println(deque.pop()); // 输出: 2(LIFO栈操作)

4. 队列与线程安全

非线程安全队列:LinkedList、PriorityQueue、ArrayDeque。

线程安全队列:

ConcurrentLinkedQueue:非阻塞线程安全队列。

BlockingQueue及其实现类:阻塞线程安全队列。

示例:生产者-消费者模式

BlockingQueue queue = new LinkedBlockingQueue<>();

// 生产者线程

new Thread(() -> {

try {

queue.put(1);

} catch (InterruptedException e) {

Thread.currentThread().interrupt();

}

}).start();

// 消费者线程

new Thread(() -> {

try {

Integer item = queue.take();

} catch (InterruptedException e) {

Thread.currentThread().interrupt();

}

}).start();

5. 队列的应用场景

消息队列:实现异步处理(如RabbitMQ、Kafka)。

任务调度:按顺序执行任务。

广度优先搜索(BFS):使用队列存储待处理节点。

缓存淘汰策略:FIFO缓存(如LinkedHashMap的removeEldestEntry方法)。

6. 注意事项

避免null元素:多数队列实现不允许null,PriorityQueue和ConcurrentLinkedQueue会直接抛出异常。

容量限制:有界队列(如ArrayBlockingQueue)需处理满队列情况,避免阻塞或拒绝操作。

迭代器:队列的迭代器可能是弱一致性的,尤其是并发队列。

总结

队列类型

有序性

线程安全

有界性

适用场景

LinkedList

FIFO

无界

灵活的双向队列操作

PriorityQueue

优先级

无界

按优先级处理元素

ArrayDeque

FIFO/LIFO

动态扩容

高效的双端操作

ConcurrentLinkedQueue

FIFO

无界

高并发场景

ArrayBlockingQueue

FIFO

有界

固定容量的线程安全队列

DelayQueue

延迟时间

无界

延迟任务调度

根据具体需求选择合适的队列实现,兼顾性能与线程安全。

相关推荐

让好习惯成为本能,这些 App 可以帮你达成「小目标」 365bet提款问题
高中数学书难度排行?📚哪些版本最难?快来揭秘!🔥 365bet提款问题
平安在身边 | “‘笑气’不可笑,危害要知道”禁毒专题宣传进行中 365bet提款问题