在使用 BlockingQueue 的应用程序中,我面临一个新需求,该需求只能通过迭代队列中存在的元素来实现(以提供有关其中元素当前状态的信息)。

根据 API Javadoc 只要求 BlockingQueue 实现的排队方法是线程安全的。 Other API methods (例如,从 Collection interface 继承的那些)可能不能同时使用,尽管我不确定这是否也适用于单纯的读取访问...

我可以安全地使用 iterator() WITHOUT altering the producer/consumer threads ,它可以随时与队列交互吗?我不需要 100% consistent iteration (在迭代队列时是否看到添加/删除元素并不重要),但我不想以讨厌的 ConcurrentModificationExceptions 结束。

请注意,该应用程序当前使用的是 LinkedBlockingQueue ,但我可以自由选择任何其他 (unbounded) BlockingQueue implementation (包括 free open-source third-party implementations )。另外,我不想依赖将来可能会损坏的东西,所以我想要一个根据 API 确定的解决方案,而不仅仅是碰巧与 current JRE 一起使用。

最佳答案

实际上,BlockingQueue 的 Java 8 javadoc 说明了这一点:



javadoc 中没有任何内容说明这仅适用于 BlockingQueue API 本身中指定的方法。



基本上,是的。 Iterator 面对并发修改的行为在实现类 javadocs 中指定。对于 LinkedBlockingQueuejavadoc 指定 Iterator 返回的 iterator()weakly consistent 。这意味着(例如)如果队列在迭代时被修改,您的应用程序将不会获得 ConcurrentModificationException,但不能保证迭代看到所有队列条目。

1 - javadoc 提到批量操作可能是非原子的,但非原子并不意味着非线程安全。这里的意思是,其他一些线程可能会在某些条目已添加(或删除,或其他)而其他条目尚未添加的状态下观察队列。

@John Vint 警告:



如果 Oracle 决定更改 javadoc 中指定的行为,那将成为迁移的障碍。过去的历史表明,Sun/Oracle 避免做那种事情。

10-07 12:40