繁体   English   中英

同步方法

[英]Synchronized Methods

如果我有一个同步的公共方法和私有方法:

public synchronized void doSomething() {
    doSomethingElse()
}

private void doSomethingElse() {
}

我需要同步私有方法吗?

这取决于:

  • 如果doSomethingElse可以安全地同时调用,那么您不需要synchronized
  • 如果不是,那么答案取决于它的调用位置:
    • 如果仅从其他synchronized方法调用它,则不需要synchronized (但是将其标记为不会造成伤害);
    • 如果可以从不synchronized方法调用它,则必须 synchronized它。

这取决于你在做什么。 您是否需要确保对doSomethingElse()串行访问?

如果是这样,并且调用doSomethingElse()的唯一事情是doSomething() ,那么不,你不需要同步。 但是如果其他一些方法可以调用doSomethingElse() ,那么是的,你也应该同步它。

NO:如果调用doSomethingElse()的唯一方法是通过另一个IS同步的方法。

可能是:如果以其他方式调用doSomethingElse() ,则通过未同步的方法,并且需要保护它免受并发访问。

这是@GuardedBy注释的意图。 如果您希望在调用该方法时必须保持锁定,请使用该方法和锁定名称对其进行注释(在示例中它将是:

@GuardedBy("this") private void doSomethingElse() {…}

然后你可以检查FindBugs的不变量是否为真。

您还可以使用其他net.jcip.annotations来描述线程安全性或缺少线程安全性,并让FindBugs验证这些假设。 当然, 这本书也需要一个插件。

从同步方法(或从synchronized块内)调用的任何方法在仍然同步的情况下运行。 如果仅从同步方法调用私有方法,则不需要单独同步私有方法。

即使代码在私有方法未同步时正常工作,从可维护性角度来看,使私有方法同步似乎也是谨慎的。

内部锁是可重入的,将synchronized关键字添加到私有方法没有任何害处。

将代码放在私有方法中会让它被其他方法调用,因此将私有方法同步以备将来从另一个方法调用它是有意义的,否则需要同步。

如果您同步一个代码块,那么从该代码块(在同一个线程上)调用的任何内容仍然保持初始锁定。 因此doSomethingElse在从doSomething调用时仍然是synchronized块的一部分。

如果你这样做:

public synchronized void doSomething() {
  new Thread() {
    public void run() {
      doSomethingElse();
    }
  }.start();
}
private void doSomethingElse() {
}

然后doSomethingElse没有 doSomething获取的锁。

还要避免使用同步方法,因为它暴露了并发策略的实现细节。 请参阅有关synchronized(this)/ synchronized方法的这个问题: 避免在Java中同步(this)?

如果必须同步doSomethingElse ,无论是否从doSomething调用它,同步doSomethingElse都不会doSomethingElse因为同步锁是可重入的(即,如果一个线程已经锁定了一个对象,它就可以获得锁定再次)。

就个人而言,我不喜欢同步方法。 我更喜欢与某种锁定变量同步,如下所示:

private final Object lock = new Object();

public void doSomething() {
  synchronized(lock) {
    // Do some safely
    doSomethingElse();
  }
  // Do some work un-safely
}

private void doSomethingElse() {
  // Do some work safely because still in lock above
  // ...
}

虽然你所做的很好,但在我看来,同步应尽可能以最低的粒度进行。 这将建议同步实际的私人功能。 目前,您假设类中没有其他函数可以独立调用私有函数。 将来情况可能并非如此。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM