当前位置: 首页 > 面试题库 >

BlockingQueue的rainingTo()方法的线程安全性

梁丘佑运
2023-03-14
问题内容

BlockingQueue的文档说,批量操作不是线程安全的,尽管它没有明确提及方法方法toitTo()。

BlockingQueue实现是线程安全的。所有排队方法都是使用内部锁或其他形式的并发控制来原子地实现其效果的。但是,除非在实现中另行指定,否则批量Collection操作addAll,containsAll,retainAll和removeAll不一定是原子执行的。因此,例如,仅在c中添加一些元素之后,addAll(c)可能会失败(引发异常)。

rainageTo()方法的文档指定了不能以线程安全的方式修改BlockingQueue元素所排放到的集合。但是,它并没有提及关于rainDate()操作具有线程安全性的任何内容。

从此队列中删除所有可用的元素,并将它们添加到给定的集合中。与重复轮询此队列相比,此操作可能更有效。尝试将元素添加到集合c时遇到故障,可能会导致在引发关联的异常时元素既不在集合中,又不在两个集合中。尝试将队列耗尽到自身会导致IllegalArgumentException。此外,如果在操作进行过程中修改了指定的集合,则此操作的行为不确定。

那么,drainTo()方法是线程安全的吗?换句话说,如果一个线程在阻塞队列上调用了dumpTo()方法,而另一个线程在同一队列上调用add()或put(),那么在两个操作结束时,队列的状态是否一致?


问题答案:

我认为您混淆了“线程安全”和“原子”这两个术语。他们不是同一件事。方法可以是线程安全的而不是原子的,并且可以是原子的(对于单个线程)而不是线程安全的。

线程安全是一个橡胶术语,很难定义而不是圆形。根据Goetz的说法,一个好的工作模型是,如果方法在多线程上下文中使用时“正确”,则该方法是线程安全的,因为该方法在单线程上下文中运行。除非您有正式的规范可用来衡量,否则,正确性是主观的。

相反,原子很容易定义。它只是意味着操作要么完全发生,要么根本不发生。

因此,您的问题的答案drainTo()是线程安全的,但不是原子的。它不是原子的,因为它可能在耗尽过程中途抛出异常。但是,以这种方式,无论其他线程是否同时对队列进行处理,队列仍将处于一致状态。

(在上面的讨论中隐含了该BlockingQueue接口的特定实现正确实现了该接口。如果未实现,则所有选择都关闭了。)



 类似资料:
  • 问题内容: 我知道文档说明该对象是线程安全的,但这是否意味着从所有方法对其进行的所有访问都是线程安全的?因此,如果我一次从多个线程中调用它,并且一次在同一实例上调用它,会不会发生什么不好的事情? 问题答案: 快速答案是肯定的,它们是线程安全的。但是不要让它在那里… 首先,一个小的内部管理是一个接口,任何不是线程安全的实现都将破坏书面合同。您包括的链接是指,它具有一定的灵巧性。 您包含的链接引起了一

  • 看起来它工作得很好,但我想知道我是否必须确保新代码需要线程安全?这里有什么意见吗?抱歉用了假名字,提前致谢。

  • IBM的支持指出,Class.GetAnnotation的实现不是线程安全的。 与其他JVM实现(例如,OpenJDK)相比,我们可以看到它们以线程安全的方式实现类方法。IBM JVM是一个闭源JVM,他们确实会发布一些源代码和他们的JVM一起,但无论什么时候他们的类实现是否线程安全,都不足以做出明确的判断。 类文档没有清楚地说明它的方法何时是线程安全的。那么,将类方法(特别是getAnnotat

  • 在并发情景下,如果只用HashMap的get方法(不用put),因为我的Map是放配置数据的,启动完成后里面的数据不会改变,线程是否安全?

  • 例如,以下方法: 我关心的是如果我有多个线程调用。对象是否可能被另一个线程覆盖?换句话说,Thread 1调用并获取返回的

  • 下面我分享了我的代码,我试图使用线程安全的Nashorn作为脚本引擎来评估简单的数学公式。公式将类似于“a*b/2”,其中a 我需要知道这种方法是否有助于使Nashorn线程在这个用例中安全。我在Attila的回答中读到,我们可以在线程之间共享脚本引擎对象,因为它们是线程安全的。 对于bindings和eval,因为我们正在为每次执行evaluate创建新线程,每个线程都有自己的bindings对