我正在清理一个遗留的java代码,我发现了以下结构:
final class QuiteComplexClass {
private Object lock = new Object();
void aMethod() {
...
synchronized(lock) {
....
}
}
}
这里是否需要用于锁定的特殊对象?当我使用简单synchronized (this)
时有什么区别?
我认为当类是公开可见的并且有人可能会错误地在类实例上调用synchronized
时,它可能很有用。但是这个类是包私有的,所以没有外部代码可以做到这一点。
不同之处在于,如果您使用this
作为锁或将方法标记为synchronized
那么另一段代码可能会意外(或故意(将您的QuiteComplexClass
对象用作锁。它可能会导致您的代码无法正常工作。如果其他开发人员决定编写如下代码,则在保持锁定时,您的代码将无法在实例上调用synchronized
方法qcc
。
synchronized(qcc) { // assuming qcc is an instance of QuiteComplexClass
while (true); // or any other time consuming operation
}
这里需要锁定的特殊对象吗?当我使用简单
synchronized (this)
时有什么区别?
简短回答:不,这不是必需的,但除了添加final
我认为删除它几乎没有好处。
我倾向于使用锁定对象,因为它们给了我更细粒度的锁,而不是锁定this
。 例如,如果要保护多个集合免受争用条件的影响,则类中可能有几个不同的锁对象。 要确定的一件事是,您应该始终确保 锁定字段final
.
private final Object lock = new Object();
也就是说,如果一个类很简单,并且您想确保人们知道哪些方法synchronized
那么在方法上使用关键字也非常合适。 正如您提到的,这是一个内部类,但即便如此,处理外部类的开发人员可能也想知道同步点。
不,这是不必要的。使用锁定对象是一种旨在避免锁定实例的模式。这是否有价值往往是一个见仁见智的问题。