一尘不染

避免在Java中同步(this)?

java

每当关于Java同步的问题浮出水面时,有些人就会很想指出synchronized(this)应该避免的事情。他们声称,取而代之的是,最好是锁定私有引用。

给出的一些原因是:

  • 一些邪恶的代码可能会窃取你的锁(非常流行,也有一个“偶然”的变体)
  • 同一类中的所有同步方法都使用完全相同的锁,这会降低吞吐量
  • 你(不必要地)暴露了太多信息

包括我在内的其他人则认为,这synchronized(this)是一个惯用语言(在Java库中也是如此),是安全且易于理解的。应当避免这种情况,因为你有一个错误,而且对多线程程序中正在发生的事情一无所知。换句话说:如果适用,请使用它。

我对看到一些真实的示例(没有foobar的东西)感兴趣,在这种情况下,避免锁定this也更可取synchronized(this)

因此:你是否应该始终避免synchronized(this)使用私有引用锁定并替换它?

一些进一步的信息(根据给出的答案进行更新):

  • 我们正在谈论实例同步
  • 的隐式(synchronized方法)和显式形式synchronized(this)都被考虑
  • 如果你引用Bloch或有关该主题的其他权威,请不要遗漏你不喜欢的部分(例如,Effective Java,Thread Safety上的项目:通常是实例本身的锁,但也有例外)。
  • 如果你需要锁定而不是synchronized(this)提供粒度,synchronized(this)则不适用,所以这不是问题

阅读 390

收藏
2020-02-27

共1个答案

一尘不染

我将分别讨论每个要点。

  1. 一些邪恶的代码可能会窃取你的锁(非常流行,但也有“偶然的”变体)

我更担心意外。这意味着该用法this是你的类的公开接口的一部分,应进行记录。有时需要其他代码使用你的锁的能力。诸如此类的事情都是如此Collections.synchronizedMap(请参阅javadoc)。

  1. 同一类中的所有同步方法都使用完全相同的锁,这会降低吞吐量

这太过简单了。仅仅摆脱synchronized(this)将无法解决问题。正确同步吞吐量需要更多考虑。

  1. 你(不必要地)暴露了太多信息

这是#1的变体。使用synchronized(this)是界面的一部分。如果你不希望/不需要暴露它,请不要这样做。

2020-02-27