是否需要同步对线程安全功能的调用?

时间:2008-11-19 10:53:37

标签: java synchronization concurrenthashmap

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

意思是:这应该同步吗?

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

5 个答案:

答案 0 :(得分:4)

由于map引用未声明final,因此可能会更改。因此,这里存在潜在的线程错误。

如果map应该是一个可变参考,那么你需要做更多的工作。否则使用final。实际上,尽可能使用final,即使它“更容易”也不行。 “final是新[旧] private。”您可能也希望map private和通用。

答案 1 :(得分:2)

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

汤姆说的是真的,你需要考虑地图参考的潜在变化。如果实际的引用没有更改,那么实际上你将在这里得到它:ConcurrentHashMap的内部同步 - 实际上通常是java.util.concurrentlibrary - 保证了对象放入地图安全地发布到其他线程。但我同意,即便如此,最好还是确定引用是否可以更改,然后在代码中明确说明(如果不能则为'final';类似'volatile'或者AtomicReference,如果它能)。

答案 2 :(得分:1)

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

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

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

-Patrick

答案 3 :(得分:0)

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

答案 4 :(得分:0)

取决于。

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

在这种情况下,如果这是您班级中唯一的方法,则无法同步对此方法的访问权限。但它不会是唯一的方法 - 因为它会让这个课程毫无意义。

如果您需要这样做以使类线程因其他原因而安全,您只需要同步此方法 - 此时,您可能想要质疑ConcurrentHashMap的开销是否值得。