每当出现关于Java同步的问题时,一些人都会非常Eager 地指出,应该避免synchronized(this)个.相反,他们声称,最好是锁定私有引用.

其中一些原因是:

包括我在内的其他人认为,synchronized(this)是一个经常使用的习惯用法(也在Java库中使用),它是安全的,并且易于理解.它不应该被避免,因为你有一个bug,你不知道你的多线程程序中发生了什么.换句话说:如果它适用,那么就使用它.

我感兴趣的是看到一些现实世界的例子(没有foobar的东西),当synchronized(this)也可以做这项工作时,避免锁定this是更可取的.

因此:should you always avoid 100 and replace it with a lock on a private reference?


更多信息(随答案更新):

  • 我们正在讨论实例同步
  • 同时考虑了隐式(synchronized种方法)和显式形式的synchronized(this)
  • 如果你引用布洛赫或其他权威人士的话,不要遗漏你不喜欢的部分(例如,有效Java,线程安全项目:Typically it is the lock on the instance itself, but there are exceptions.))
  • 如果在锁定中需要synchronized(this)以外的粒度,那么synchronized(this)不适用,所以这不是问题所在

推荐答案

我将分别讨论每一点.

  1. 一些恶意代码可能会窃取您的锁(非常流行的这一个,还有一个 "意外"变体)

    我更担心accidentally.实际上,使用this是类的公开接口的一部分,应该记录在案.有时需要其他代码使用您的锁.Collections.synchronizedMap(参见javadoc)之类的东西也是如此.

  2. 同一类中的所有同步方法使用完全相同的

    这是过于简单化的 idea ,仅仅go 掉synchronized(this)个并不能解决问题.吞吐量的正确同步需要更多考虑.

  3. 你(不必要地)expose 了太多的信息

    这是#1的变体.使用synchronized(this)是界面的一部分.如果你不想/不需要expose ,不要这样做.

Java相关问答推荐

通过推送通知向自己发送Matrix消息

Cosmos Change Feed Process Lag远远超过收集中的记录数量

Java中后期绑定的替代概念

S的字符串表示是双重精确的吗?

是否在允许数组元素为空时阻止 idea 为空性警告?

多重延迟签名

对于亚洲/香港,使用ResolverStyle.STRICT的LocalDate.parse返回意外结果

自定义批注的外推属性值

SonarLint:只能有条件地调用方法(S)

Java中将文本拆分为数字或十进制数字和字符串

如何在antlr4中跳过所有反斜杠-换行符而保留换行符?

Java SSLKeyManager出厂密码

Java 11 HttpCookie.parse在解析包含JSON的Cookie时引发IlLegalArgumentException

Quarkus:运行时出现EnumConstantNotPresentException

我的代码是线程安全的吗?[Java、CAS、转账]

循环不起作用只有第一个元素重复

通过/失败的参数化junit测试方法执行数

HBox内部的左对齐按钮(如果重要的话,在页码内)

如果c不为null,Arrays.sort(T[]a,Comparator<;?super T>;c)是否会引发ClassCastException?

如何使用命令行为Java应用程序生成烟雾测试用例