BlockingQueue的文档说批量操作不是线程安全的,尽管它没有明确提到方法 drainTo()。
BlockingQueue 实现是线程安全的。所有排队方法都使用内部锁或其他形式的并发控制以原子方式实现其效果。但是,批量收集操作 addAll、containAll、retainAll 和 removeAll 不一定以原子方式执行,除非在实现中另外指定。因此,例如,addAll(c) 在仅添加 c 中的一些元素后可能会失败(抛出异常)。
drainTo() 方法的文档指定不能以线程安全的方式修改 BlockingQueue 的元素所排放到的集合。但是,它没有提到任何关于 drainTo() 操作是线程安全的。
从此队列中删除所有可用元素并将它们添加到给定集合中。此操作可能比重复轮询此队列更有效。尝试将元素添加到集合 c 时遇到的失败可能会导致在引发相关异常时元素既不在集合中,又不属于任何一个集合或两个集合。尝试将队列排空到自身会导致 IllegalArgumentException。此外,如果在操作正在进行时修改了指定的集合,则此操作的行为是未定义的。
那么,drainTo() 方法是线程安全的吗?换句话说,如果一个线程在阻塞队列上调用了 drainTo() 方法,而另一个线程在同一个队列上调用了 add() 或 put(),那么在这两个操作结束时队列的状态是否一致?