You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多线程调用LinkedList.poll()是否需同步或使用并发List?

关于多线程调用LinkedList.poll()的线程安全问题

嘿,这个问题抓得很准!咱们直接说重点:

核心结论

你必须做线程安全控制,要么手动同步LinkedList的poll()调用,要么直接用Java并发包提供的线程安全队列实现——因为原生的LinkedList根本不是线程安全的,多线程同时调用poll()会出问题。

为什么原生LinkedList不行?

LinkedList的poll()方法内部要做几件事:检查头节点是否为空,不为空的话就修改头节点引用、断开旧头节点的链接。这些操作没有任何同步保护,多线程同时执行时会触发竞态条件:

  • 可能出现两个线程同时拿到同一个头节点,导致重复获取元素;
  • 更严重的可能破坏链表结构,比如节点引用丢失、甚至引发死循环,后续操作直接报错。
    完全不符合你“无重复元素”的要求。

两种可行解决方案

1. 手动给LinkedList加同步控制

如果一定要用现有的LinkedList实例,那每次调用poll()都必须在同步块里执行,确保同一时间只有一个线程能操作链表:

// 用synchronized块包裹调用
synchronized(yourLinkedList) {
    return yourLinkedList.poll();
}

或者用ReentrantLock来实现同步,灵活度更高,适合复杂场景。不过这种方式本质上是把并发操作变成了串行,高并发下性能会打折扣。

2. 改用并发队列实现(更推荐)

Java并发包已经给我们做好了现成的解决方案,直接用ConcurrentLinkedQueue就完美适配你的需求:

  • 它的poll()方法本身就是线程安全的,基于CAS操作实现无锁并发,性能比同步LinkedList好很多;
  • 空队列时poll()返回null,和LinkedList的poll()行为完全一致,不需要改太多代码。
    另外如果需要阻塞等待的场景,LinkedBlockingQueue也是选项,但你的场景用ConcurrentLinkedQueue更合适。

测试建议

你写测试的时候,可以这么做:

  • 初始化一个装满元素的队列;
  • 启动N个线程,每个线程循环调用poll()直到返回null,把自己拿到的元素存起来;
  • 所有线程结束后,把所有线程的结果合并,检查是否有重复元素,同时看总元素数是否和初始元素数一致;
  • 额外观察是否有ConcurrentModificationException或者其他异常抛出,验证线程安全的有效性。

内容的提问来源于stack exchange,提问作者Sikorski

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 06:46:34