[英]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.