peek() 方法返回队头元素且不移除,队列为空时返回 null;它线程安全、非阻塞、不修改队列结构,并可用于空队列判断,但存在弱一致性风险。

ConcurrentLinkedQueue 的 peek() 方法可以直接获取队头元素而不移除它,这是它的标准行为,无需额外操作。
peek() 的作用就是“只看不取”
该方法返回队列头部的元素,如果队列为空则返回 null。它不会改变队列结构,也不影响后续的并发操作。
- 线程安全:内部使用无锁(lock-free)CAS机制,多线程调用
peek()不会阻塞或竞争锁 - 非阻塞:即使队列为空也立即返回
null,不会等待元素入队 - 不修改队列:无论返回什么值,队头元素仍保留在原位置,下次
poll()或再次peek()仍能访问到它
典型用法示例
以下代码展示了如何安全地检查队头元素:
ConcurrentLinkedQueue<string> queue = new ConcurrentLinkedQueue();
queue.offer("first");
queue.offer("second");
String head = queue.peek(); // 返回 "first",队列仍为 ["first", "second"]
System.out.println(head); // 输出: first
head = queue.peek(); // 再次调用,仍返回 "first"
System.out.println(queue.size()); // 输出: 2,大小未变
</string>
注意空队列和 null 元素的边界情况
peek() 在队列为空时返回 null,但要注意:ConcurrentLinkedQueue 不允许存入 null 元素,所以返回 null 唯一含义就是队列为空。
- 判断是否为空:直接用
queue.peek() == null是可靠方式(比queue.isEmpty()更轻量,且语义一致) - 避免 NPE:使用前建议判空,尤其在多线程环境下,可能刚
peek()返回非 null,下一刻就被其他线程poll()掉了 - 不保证实时一致性:由于是弱一致性迭代器模型,
peek()返回的值反映的是调用瞬间的逻辑头节点,但无法保证该节点在返回后一定还“有效”(比如正被其他线程删除中)
和 poll()、element() 的区别要清楚
三者都面向队头,但行为不同:
-
peek():安全查看,返回null表示空 -
poll():取出并移除队头,同样返回null表示空 -
element():查看队头,但队列为空时抛NoSuchElementException,一般少用
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











