在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.offer("A");
queue.offer("B");
System.out.println(queue.poll()); // 输出: A
2.2 PriorityQueue
特点:基于优先级堆实现,元素按自然顺序或指定比较器排序。
注意:不允许null元素,非线程安全。
Queue
priorityQueue.offer(3);
priorityQueue.offer(1);
System.out.println(priorityQueue.poll()); // 输出: 1(最小元素优先)
2.3 ArrayDeque
特点:动态数组实现的双端队列,不允许null元素。
优势:无容量限制,比LinkedList在队列操作上更高效。
Deque
deque.offerFirst("A");
deque.offerLast("B");
System.out.println(deque.pollLast()); // 输出: B
2.4 ConcurrentLinkedQueue
特点:基于链表的无界线程安全队列,采用CAS(Compare-and-Swap)操作。
适用场景:高并发环境。
Queue
concurrentQueue.offer("Task1");
concurrentQueue.poll(); // 线程安全操作
2.5 BlockingQueue接口及实现类
用于线程间通信,支持阻塞操作(如put()和take())。
ArrayBlockingQueue:有界数组实现的阻塞队列。
LinkedBlockingQueue:可选有界的链表阻塞队列。
PriorityBlockingQueue:支持优先级的无界阻塞队列。
DelayQueue:延迟元素的无界阻塞队列,元素必须实现Delayed接口。
BlockingQueue
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.push(1); // 等价于 addFirst()
deque.push(2);
System.out.println(deque.pop()); // 输出: 2(LIFO栈操作)
4. 队列与线程安全
非线程安全队列:LinkedList、PriorityQueue、ArrayDeque。
线程安全队列:
ConcurrentLinkedQueue:非阻塞线程安全队列。
BlockingQueue及其实现类:阻塞线程安全队列。
示例:生产者-消费者模式
BlockingQueue
// 生产者线程
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
延迟时间
是
无界
延迟任务调度
根据具体需求选择合适的队列实现,兼顾性能与线程安全。