对线程安全函数的调用也需要同步吗?
如果我使用 ConcurrentHashMap (其中 put 是线程安全的),并且我提供了一个使用 ConcurrentHashMap put 的公共函数 myPut - 我是否需要同步我的函数?
含义:这应该同步吗?
ConcurrentHashMap map;
public void myPut(int something) {
this.map.put(something);
}
If I'm using ConcurrentHashMap (where the put is thread safe) , and I supply a public function myPut that uses the ConcurrentHashMap put - do I need to synchronize my function?
meaning : should this be synchronized?
ConcurrentHashMap map;
public void myPut(int something) {
this.map.put(something);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
由于
map
引用未声明为final
,因此可能会发生更改。 因此,这里存在潜在的线程错误。如果
map
应该是一个可变引用,那么您将需要做更多的工作。 否则使用final
。 事实上,只要有可能,就使用final
,即使不这样做“更容易”。 “final
是新的[旧]private
。” 您可能还想使map
private
和通用。Because the
map
reference is not declaredfinal
it may be changed. Therefore, there is a potential threading bug here.If
map
is supposed to be a mutable reference then you will need to do some more work. Otherwise usefinal
. Indeed, usefinal
whenever you can, even if it is "easier" not to. "final
is the new [old]private
." You probably want to makemap
private
and generic too.ConcurrentHashMap 等并发实用程序的设计使您无需同步:它们将在内部处理线程安全访问。
汤姆说的是真的,您需要考虑地图参考更改的潜力。 如果引用实际上没有改变,那么实际上你会在这里逃脱:ConcurrentHashMap的内部同步——实际上是一般的java.util.concurrentlibrary——保证对象放入地图中的内容会安全地发布到其他线程。 但我同意,即便如此,决定引用是否可以更改,然后在代码中明确声明这一点是一个很好的做法(如果不能,则为“final”;如果可以,则为“volatile”或 AtomicReference 之类的内容)能)。
Concurrency utilities such as ConcurrentHashMap are designed so that you don't need to synchronize: they'll handle thread-safe access internally.
What Tom says is true, that you need to think about the potential of the map reference to change. If the reference actually doesn't change, then in practice you'll get away with it here: the internal synchronization of ConcurrentHashMap -- and indeed the java.util.concurrentlibrary in general -- guarantees that objects put into the map are safely published to other threads. But I would agree that even so, it is good practice to decide whether the reference can change or not, and then explicitly state this in the code ('final' if it can't; something like 'volatile' or an AtomicReference if it can).
如果您使用 ConcurrentHashMap,则不应同步“put”,但这并不意味着您的“put”将一次被调用一次。 这取决于你Map的并发级别...
所以你必须知道你想要什么。
顺便说一句,看看 ConcurrentHashTable Javadoc,一切都解释得很好......-
Patrick
If you use a ConcurrentHashMap you shouldn't synchronize 'put' but it doesn't mean your 'puts' will be called one a time. This depends on the concurrency level of you Map...
So you have to know what you want.
BTW have a look at the ConcurrentHashTable Javadoc, everything is well explained...
-Patrick
这取决于。
当您为将从多个线程使用的对象编写类时,整个游戏就会发生变化。 如果您希望提供任何线程安全保证,您需要了解您想要实现的结果。
在这种情况下,如果这是类中唯一的方法,则同步对此方法的访问是没有意义的。 但这并不是唯一的方法——因为它会让课程变得毫无意义。
仅当您因其他原因需要同步此方法以使类线程安全时,您才需要同步此方法 - 此时,您可能想质疑 ConcurrentHashMap 的开销是否值得。
It depends.
When you are writing the classes for objects that will be used from multiple threads, the whole game changes. You need to understand what results you are trying to achieve if you hope to provide any thread safety guarantees.
In this case, if this is the only method in your class, there is no point in synchronizing access to this method. But it won't be the only method - for it would make the class pretty pointless.
You only need to synchronize this method if you need to do so to make the class thread safe for other reasons - at which point, you might want to question whether the overhead of a
ConcurrentHashMap
is worthwhile.编号
您可以一次多次调用 myPut。
put 会一次调用一个,因为 HashTable 的访问需要一次一个。 (另请参阅共享内存中的并发写入)
No.
You can cal myPut multiple times at once.
The put will be called one at a time, because the HashTable's access needs to be one at a time. (see also concurrent writing in a shared memory)