ConcurrentLinkedQueue 的入队操作使用线程安全、无锁、基于 CAS 的 offer(E e) 方法,不接受 null 元素,保证 happens-before 可见性,且不抛出异常(除 NullPointerException 外)。

ConcurrentLinkedQueue 的入队操作使用 offer(E e) 方法,这是线程安全的、无锁(lock-free)的非阻塞入队方式。
入队方法是 offer(),不是 add()
虽然 ConcurrentLinkedQueue 实现了 Queue 接口,但推荐始终使用 offer(E e) 入队。它在成功时返回 true,且**永远不会抛出异常**(即使传入 null 也会直接抛出 NullPointerException)。不建议用 add(),因为它的语义是“失败时抛异常”,而该队列实际不会因容量满而失败(它是无界队列),所以 add() 只是简单委托给 offer(),没有额外价值。
入队过程是无锁且基于 CAS 的
底层通过原子操作(Compare-And-Swap)更新尾节点的 next 指针完成插入,整个过程不加锁、不阻塞线程。这意味着:
- 多个线程可同时调用
offer(),彼此不会等待 - 入队操作的平均时间复杂度为 O(1),最坏情况可能略高(如需跳过已删除节点或帮助推进尾节点),但仍是分摊常数时间
- 无需担心死锁或线程饥饿问题
注意 null 值不允许
ConcurrentLinkedQueue 明确禁止 null 元素。一旦传入 null,offer(null) 会立即抛出 NullPointerException。这不是运行时检查失败,而是设计上的硬性约束——因为 null 被用来标记链表末尾或删除状态,无法区分“空元素”和“结束标志”。
立即学习“Java免费学习笔记(深入)”;
升级报告:增加动态新闻功能后台添加,删除,编辑,支持UBB代码,支持上传片及文件。 增加我要入团功能散客可以自由选择加入贵社最近要出发的团队。 增加线路置顶功能置顶后的线路永远显示在最前面。 增加同行报价功能管理员在后台添加同行用户,同行用户登录后可查看贵社线路对同行的报价。同行报价在添加线路中一并添加。(感谢网友拽哥提出修改意见) 增加更多线路显示的分页功能方便大型旅行社由于线路过多而引起的部分
queue.offer(null); // 抛出 NullPointerExceptionqueue.offer("item"); // 正常入队
入队后不保证立即对其他线程可见?不,它保证 happens-before
得益于内部使用的 volatile 读写和 CAS,每次成功的 offer() 都建立一个 happens-before 关系。也就是说:一个线程 A 成功入队后,另一个线程 B 后续调用 poll() 或 peek() 有合理机会看到该元素(具体取决于执行时序和队列状态),JVM 和 CPU 不会因重排序导致“入队了却看不到”的问题。
基本上就这些。入队本身很简单,关键是理解它背后无锁、不可空、强可见性的设计约束。










