【问题标题】:ConcurrentLinkedQueue QuestionsConcurrentLinkedQueue 问题
【发布时间】:2010-01-07 13:42:26
【问题描述】:

您能否澄清一下我们是否需要使用显式同步或锁定来使用 ConcurrentLinkedQueue?我特别想知道以下 ConcurrentLinkedQueue 方法是否需要同步调用。

  • 添加
  • 清除
  • 尺寸

可能 size 是唯一可能需要显式同步的方法,因为它不是原子方法,但 ConcurrentLinkedQueue java 文档说

“请注意,与大多数 集合,大小方法不是 恒定时间操作。因为 这些的异步性质 队列,确定当前数量 of 元素需要遍历 要素。 "

这让我相信虽然 size 调用可能很慢,但它不需要任何显式同步调用。

提前致谢...

【问题讨论】:

    标签: java concurrency


    【解决方案1】:

    clear() 不是原子操作(它在 AbstractQueue 类中实现),正如 Javadoc 和源代码所说:“这个实现重复调用 poll 直到它返回 null。”。 poll 是原子的,但是如果你在 clear() 正在进行的时候使用 offer,你会在 clear() 过程中添加一些东西,而 clear() 会删除它...

    如果你将使用 clear(),你应该使用 LinkedBlockingQueue 而不是 ConcurrentLinkedQueue。

    【讨论】:

      【解决方案2】:

      您不需要任何显式同步或锁定。作为the docs 状态,它是一个线程安全 集合。这意味着这些方法中的每一个都是正确的原子方法(尽管正如您所指出的,size() 可能很慢)。

      【讨论】:

        【解决方案3】:

        您不应该也不需要对任何这些方法使用显式锁定。

        【讨论】:

          【解决方案4】:

          是的,您不需要使用显式同步,因为这是一个线程安全的集合。任何并发访问都可以放心

          【讨论】:

            【解决方案5】:

            不需要同步来保留队列的内部结构。但是,可能需要对结构的其他不变量进行线性化。

            例如size() 在任何共享的可变容器中都毫无意义。它所能告诉您的只是您上次询问的内容,而不是现在的情况,除非您停止世界并防止并发修改。它仅用于指示性监控目的,您应该永远在您的算法中使用它。

            同样,clear() 在没有某种外部干预的情况下并没有多大意义。清楚什么?你说清楚的时候里面的东西?在并发结构中,回答 是一个即使不是不可能的问题也很困难的问题。

            因此,您最好将其用作简单的线程安全队列(仅提供和轮询)并避开其他队列,除非您进行外部锁定。

            【讨论】:

              猜你喜欢
              • 2010-11-28
              • 2011-02-15
              • 2010-10-11
              • 2013-09-12
              • 2016-11-16
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多