避免在方法级别使用同步。

huangapple go评论78阅读模式
英文:

Avoid synchronized at method level

问题

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

但是在这个规则中,PMD建议以下示例:Synchronized on method rule

public class Foo {
  // 尽量避免这种写法:
  synchronized void foo() {
  }
  // 更倾向于这种写法: <----- 为什么?在字节码级别上不是一样吗?
  void bar() {
    synchronized(this) {
    }
  }
}

这个示例中的PMD规则是否有规范上的错误,或者在方法上使用synchronizedsynchronized(this)有不同的工作方式?

英文:

PMD (source code analyzer) recommends to avoid synchronized at method level.
It is actually obvious as when you call synchronized on method you are calling synchronized on this and that can lead to potential issues.

But PMD in this rule suggests the following example: 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) {
    }
  }
}

Is it a bug in a specification of PMD (in the example) or synchronized on method works differently from synchronized(this)?

答案1

得分: 3

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

你贴出的链接很好地解释了原因:

"方法级别的同步在向方法中添加新代码时可能会引发问题。块级别的同步有助于确保只有需要同步的代码才会被同步。"

英文:

Yes, it is technically the same. This is about code style, not correctness.

The link you posted explains the reason quite well:

> 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.

答案2

得分: 1

NOS_NON_OWNED_SYNCHRONIZATION
这个方法使用了一个同步块,其中被同步的对象并不由当前实例拥有。这意味着其他实例可能会使用相同的对象来进行自己的同步,导致同步混乱。最好的做法是只对该类的私有字段进行同步。注意,“this”并不属于当前实例,而是属于将其分配给其类字段的人。对“this”进行同步也不是一个好主意。

与Spotbugs规则一起使用时,最好的风格是不要同步整个方法体。

英文:

An additional rule in SB_CONTRIB discourages use of this in synchronized since the class object can be used by other threads to lock on as well.

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

NOS_NON_OWNED_SYNCHRONIZATION
This method uses a synchronize block where the object that is being synchronized on, is not owned by this current instance. This means that other instances may use this same object for synchronization for their own purposes, causing synchronization confusion. It is always cleaner and safer to only synchronize on private fields of this class. Note that 'this' is not owned by the current instance, but is owned by whomever assigns it to a field of its class. Synchronizing on 'this' is also not a good idea.

In conjunction with this Spotbugs rule, it is more than good style to not synchronize the entire method body.

答案3

得分: 1

"correct" versions是PMD文档中的错误,至少如此。

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

英文:

The “correct” versions are bugs in the PMD documentation, at the very least.

The point of the rule is to indicate that placing an entire method body in a synchronization block is probably unnecessary; in most cases, only the code accessing a multi-threaded resource needs to be synchronized. So the examples should show, or imply, that there is some code before and/or after the synchronized block.

huangapple
  • 本文由 发表于 2020年7月28日 18:42:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/63132263.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定