避免在方法级别同步

Avoid synchronized at method level

PMD(源代码分析器)建议在方法级别避免 synchronized。 这实际上很明显,当您在 this 上同步调用的方法上调用 synchronized 时,这可能会导致潜在的问题。

但此规则中的 PMD 建议使用以下示例:Synchronized on method rule

public class Foo {
  // Try to avoid this:
  synchronized void foo() {
  }
  // Prefer this: <----- Why? Isn't it the same on byte-code level
  void bar() {
    synchronized(this) {
    }
  }
}

它是 PMD 规范中的错误(在示例中)还是 synchronized on 方法的工作方式与 synchronized(this) 不同?

是的,技术上是一样的。这是关于代码风格,而不是正确性。

你发的link很好的解释了原因:

Method-level synchronization can cause problems when new code is added to the method. Block-level synchronization helps to ensure that only the code that needs synchronization gets it.

SB_CONTRIB 中的附加规则不鼓励在 synchronized 中使用它,因为 class 对象也可以被其他线程用来锁定。

http://fb-contrib.sourceforge.net/bugdescriptions.html

NOS_NON_OWNED_SYNCHRONIZATION 此方法使用同步块,其中正在同步的对象不属于当前实例。这意味着其他实例可能会出于自己的目的使用同一对象进行同步,从而导致同步混乱。仅在 class 的私有字段上同步总是更干净、更安全。请注意,'this' 不属于当前实例,但属于将其分配给其 class 字段的任何人。在 'this' 上同步也不是一个好主意。

结合这个 Spotbugs 规则,不同步整个方法体是非常好的风格。

“正确”版本至少是 PMD 文档中的错误。

规则的要点是表明将整个方法体放在同步块中可能是不必要的;在大多数情况下,只有访问多线程资源的代码需要同步。因此示例应该显示或暗示在同步块之后 and/or 之前有一些代码。