- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
BlockingQueue 的文档说批量操作不是线程安全的,尽管它没有明确提到方法 drainTo()。
BlockingQueue implementations are thread-safe. All queuing methods achieve their effects atomically using internal locks or other forms of concurrency control. However, the bulk Collection operations addAll, containsAll, retainAll and removeAll are not necessarily performed atomically unless specified otherwise in an implementation. So it is possible, for example, for addAll(c) to fail (throwing an exception) after adding only some of the elements in c.
drainTo() 方法的文档指定不能以线程安全的方式修改 BlockingQueue 的元素被排放到的集合。但是,它没有提到 drainTo() 操作是线程安全的。
Removes all available elements from this queue and adds them to the given collection. This operation may be more efficient than repeatedly polling this queue. A failure encountered while attempting to add elements to collection c may result in elements being in neither, either or both collections when the associated exception is thrown. Attempts to drain a queue to itself result in IllegalArgumentException. Further, the behavior of this operation is undefined if the specified collection is modified while the operation is in progress.
那么,drainTo() 方法是线程安全的吗?换句话说,如果一个线程在阻塞队列上调用了 drainTo() 方法,而另一个线程在同一队列上调用了 add() 或 put() 方法,那么在两个操作结束时队列的状态是否一致?
最佳答案
我认为您混淆了“线程安全”和“原子”这两个术语。它们的意思不同。一个方法可以是线程安全的而不是原子的,并且可以是原子的(对于单个线程)而不是线程安全的。
线程安全是一个橡胶术语,如果不循环使用就很难定义。根据 Goetz 的说法,一个好的工作模型是,如果方法在多线程上下文中使用时与在单线程上下文中运行时“一样正确”,则该方法是线程安全的。弹性在于正确性是主观的,除非你有一个正式的规范来衡量。
相比之下,atomic 很容易定义。它只是意味着操作要么完全发生,要么根本不发生。
所以你的问题的答案是 drainTo()
是线程安全的,但不是原子的。它不是原子的,因为它可能会在耗尽过程中抛出异常。然而,取模后,队列仍将处于一致状态,无论其他线程是否同时对队列执行操作。
(在上面的讨论中暗示BlockingQueue
接口(interface)的具体实现正确地实现了接口(interface)。如果没有,则所有赌注都将关闭。)
关于java - BlockingQueue 的 drainTo() 方法的线程安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6607195/
我是一名优秀的程序员,十分优秀!