问题描述
每当在SO上弹出一个关于Java同步的问题时,有些人非常渴望指出应该避免 synchronized(this)
。相反,他们声称,首选锁定私人参考。
Whenever a question pops up on SO about Java synchronization, some people are very eager to point out that synchronized(this)
should be avoided. Instead, they claim, a lock on a private reference is to be preferred.
一些给定的原因是:
- (非常受欢迎,也有意外变体)
- some evil code may steal your lock (very popular this one, also has an "accidentally" variant)
- all synchronized methods within the same class use the exact same lock, which reduces throughput
- you are (unnecessarily) exposing too much information
其他人,包括我在内,认为已同步(这个)
是一个被大量使用的习惯用法(也在Java库中),是安全且易于理解的。不应该避免它,因为你有一个错误,你不知道多线程程序中发生了什么。换句话说:如果适用,则使用它。
Other people, including me, argue that synchronized(this)
is an idiom that is used a lot (also in Java libraries), is safe and well understood. It should not be avoided because you have a bug and you don't have a clue of what is going on in your multithreaded program. In other words: if it is applicable, then use it.
我有兴趣看到一些现实世界的例子(没有foobar的东西)避免锁定这个
最好是 synchronized(this)
也可以完成这项工作。
I am interested in seeing some real-world examples (no foobar stuff) where avoiding a lock on this
is preferable when synchronized(this)
would also do the job.
因此:你应该总是避免 synchronized(this)
并将其替换为私人引用上的锁吗?
Therefore: should you always avoid synchronized(this)
and replace it with a lock on a private reference?
更多信息(根据答案更新):
Some further info (updated as answers are given):
- 我们讨论的是实例同步
- 隐式(
synchronized
方法)和显式形式synchronized (这)
被认为是 - 如果你引用Bloch或其他有关主题的权威,不要遗漏你不喜欢的部分(例如Effective Java) ,线程安全项目:通常它是实例本身的锁定,但也有例外。)
- 如果您需要锁定o的粒度o比
synchronized(this)
提供,然后synchronized(this)
不适用,这不是问题
- we are talking about instance synchronization
- both implicit (
synchronized
methods) and explicit form ofsynchronized(this)
are considered - if you quote Bloch or other authorities on the subject, don't leave out the parts you don't like (e.g. Effective Java, item on Thread Safety: Typically it is the lock on the instance itself, but there are exceptions.)
- if you need granularity in your locking other than
synchronized(this)
provides, thensynchronized(this)
is not applicable so that's not the issue
推荐答案
我将分别涵盖每一点。
我更担心意外。它相当于使用这个
是你的类暴露界面的一部分,应该记录在案。有时需要其他代码使用锁的能力。这类似于 Collections.synchronizedMap
(参见javadoc)。
I'm more worried about accidentally. What it amounts to is that this use of this
is part of your class' exposed interface, and should be documented. Sometimes the ability of other code to use your lock is desired. This is true of things like Collections.synchronizedMap
(see the javadoc).
这过于简单化思维;只是摆脱 synchronized(this)
将无法解决问题。适当的吞吐量同步需要更多考虑。
This is overly simplistic thinking; just getting rid of synchronized(this)
won't solve the problem. Proper synchronization for throughput will take more thought.
这是#1的变体。使用 synchronized(this)
是您界面的一部分。如果您不希望/需要暴露,请不要这样做。
This is a variant of #1. Use of synchronized(this)
is part of your interface. If you don't want/need this exposed, don't do it.
这篇关于在Java中避免同步(this)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!