hello啊,各位观众姥爷们!!!本baby今天来报道了!哈哈哈哈哈嗝
队列(Queue)是 Java 集合框架中一种 先进先出(FIFO) 的线性数据结构,广泛应用于生产者-消费者模型、任务调度、线程池等场景。Java 提供了丰富的队列实现,涵盖线程安全、阻塞、优先级等特性。
Java 队列的顶层接口是 java.util.Queue
,定义以下核心方法:
方法 | 描述 | 异常行为 | 返回值行为 |
---|---|---|---|
add(E e) |
插入元素到队尾,若队列已满抛出异常 | 抛出 IllegalStateException |
成功返回 true |
offer(E e) |
插入元素到队尾,不抛异常 | 返回 false (队列满时) |
成功返回 true |
remove() |
移除并返回队头元素,队列为空时抛出异常 | 抛出 NoSuchElementException |
返回移除的元素 |
poll() |
移除并返回队头元素,队列为空时返回 null |
返回 null |
返回移除的元素或 null |
element() |
查看队头元素(不移除),队列为空时抛出异常 | 抛出 NoSuchElementException |
返回队头元素 |
peek() |
查看队头元素(不移除),队列为空时返回 null |
返回 null |
返回队头元素或 null |
Java 提供了多种队列实现,按功能可分为以下几类:
LinkedList
:基于链表的队列,支持快速插入/删除(非线程安全)。
Queue<String> queue = new LinkedList<>();
queue.offer("A"); // 添加元素
String head = queue.poll(); // 移除并返回队头元素
PriorityQueue
:基于堆的优先级队列,元素按自然顺序或自定义 Comparator
排序。
Queue<Integer> pq = new PriorityQueue<>();
pq.offer(5); pq.offer(1); pq.offer(3);
while (!pq.isEmpty()) {
System.out.println(pq.poll()); // 输出顺序:1, 3, 5
}
线程安全的队列,支持阻塞操作(生产者-消费者模型的核心组件):
ArrayBlockingQueue
:基于数组的有界阻塞队列。
BlockingQueue<String> queue = new ArrayBlockingQueue<>(100);
queue.put("Task1"); // 阻塞直到队列有空位
String task = queue.take(); // 阻塞直到队列非空
LinkedBlockingQueue
:基于链表的阻塞队列,默认无界(可指定容量)。
PriorityBlockingQueue
:带优先级的无界阻塞队列。
SynchronousQueue
:不存储元素的队列,直接传递任务(一对一通信)。
ConcurrentLinkedQueue
:基于 CAS 的无锁并发队列,高性能但无阻塞语义。ConcurrentLinkedQueue<String> queue = new ConcurrentLinkedQueue<>();
queue.offer("Data");
String data = queue.poll();
支持在队列两端插入/删除元素:
ArrayDeque
:基于数组的高效双端队列。任务调度与线程池
// 线程池使用 LinkedBlockingQueue 作为任务队列
ExecutorService executor = new ThreadPoolExecutor(
2, 5, 60, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(100)
);
executor.submit(() -> System.out.println("Task executed"));
生产者-消费者模型
BlockingQueue<Integer> queue = new LinkedBlockingQueue<>();
// 生产者线程
new Thread(() -> {
while (true) {
int data = generateData();
queue.put(data); // 阻塞直到队列有空位
}
}).start();
// 消费者线程
new Thread(() -> {
while (true) {
int data = queue.take(); // 阻塞直到队列非空
processData(data);
}
}).start();
广度优先搜索(BFS)
Queue<Node> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
Node node = queue.poll();
for (Node neighbor : node.neighbors) {
queue.offer(neighbor);
}
}
当队列满或空时,阻塞队列支持以下策略:
策略 | 对应方法 | 行为 |
---|---|---|
抛异常 | add(e) / remove() |
队列满或空时抛出异常 |
返回特殊值 | offer(e) / poll() |
队列满返回 false ,空返回 null |
阻塞等待 | put(e) / take() |
阻塞直到队列可操作 |
超时等待 | offer(e, timeout) |
在指定时间内尝试操作,超时失败 |
线程安全需求:
LinkedList
、ArrayDeque
。ConcurrentLinkedQueue
(非阻塞)或 LinkedBlockingQueue
(阻塞)。容量限制:
ArrayBlockingQueue
)防止 OOM。LinkedBlockingQueue
)。优先级需求:
PriorityBlockingQueue
。性能调优:
ConcurrentLinkedQueue
或 Disruptor(高性能环形队列库)。Sequence
设计)。线程安全陷阱:
LinkedList
和 PriorityQueue
非线程安全,多线程环境下需手动同步或使用并发队列。阻塞队列的死锁风险:
优先级队列的排序一致性: