【问题标题】:Does a call to a threadsafe function need to be syncronized too?对线程安全函数的调用是否需要同步?
【发布时间】:2008-11-19 10:53:36
【问题描述】:

如果我使用 ConcurrentHashMap(其中 put 是线程安全的),并且我提供了一个使用 ConcurrentHashMap put 的公共函数 myPut - 我需要同步我的函数吗?

意思:应该同步吗?

ConcurrentHashMap map;  
public void myPut(int something) {  
   this.map.put(something);  
}

【问题讨论】:

    标签: java synchronization concurrenthashmap


    【解决方案1】:

    因为map 引用未声明final,所以它可能会被更改。因此,这里存在潜在的线程错误。

    如果map 应该是一个可变引用,那么您将需要做更多的工作。否则使用final。事实上,尽可能使用final,即使它“更容易”不使用。 “final 是新的 [旧] private。”您可能也想制作 map private 和泛型。

    【讨论】:

      【解决方案2】:

      ConcurrentHashMap 等并发实用程序的设计使您无需同步:它们将在内部处理线程安全访问。

      Tom 说的是真的,您需要考虑地图参考的变化潜力。如果引用实际上没有改变,那么实际上你会在这里摆脱它:ConcurrentHashMap 的内部同步——实际上是 java.util.concurrentlibrary——保证对象放入地图中会安全地发布到其他线程。但我同意即便如此,最好还是决定引用是否可以更改,然后在代码中明确说明这一点(如果不能,则为“最终”;如果可以,则为“易失性”或 AtomicReference可以)。

      【讨论】:

        【解决方案3】:

        如果您使用 ConcurrentHashMap,则不应同步“put”,但这并不意味着您的“puts”将被调用一次。这取决于您 Map 的并发级别...

        所以你必须知道你想要什么。

        顺便看看 ConcurrentHashTable Javadoc,一切都很好解释...

        -帕特里克

        【讨论】:

          【解决方案4】:

          视情况而定。

          当您为要从多个线程使用的对象编写类时,整个游戏都会发生变化。如果您希望提供任何线程安全保证,您需要了解您想要达到的结果。

          在这种情况下,如果这是你的类中唯一的方法,那么同步访问这个方法是没有意义的。但它不会是唯一的方法 - 因为它会使课程变得毫无意义。

          仅当出于其他原因需要同步此方法以使类线程安全时,您才需要同步此方法 - 此时,您可能想质疑 ConcurrentHashMap 的开销是否值得。

          【讨论】:

            【解决方案5】:

            没有。
            您可以一次调用 myPut 多次。
            put 将一次调用一个,因为 HashTable 的访问需要一次一个。 (另见共享内存中的并发写入)

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2011-09-16
              • 2016-05-08
              • 1970-01-01
              • 1970-01-01
              • 2010-11-06
              • 1970-01-01
              • 2016-11-14
              相关资源
              最近更新 更多