java 为什么抽象方法不能同步?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12805698/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why can't an abstract method be synchronized?
提问by ahodder
I was reading a thread from CodeRanchsaying that abstract methods could not be synchronized due to the fact that an abstract class cannot be instantiated, meaning no object to lock.
我正在阅读CodeRanch 的一个线程,说抽象方法无法同步,因为抽象类无法实例化,这意味着没有要锁定的对象。
This doesn't make sense since an abstract class is a definition (contract) for a child class. The abstract definition of a synchronized method does not need to lock, the child does. All the abstract heading would indicate is that the child mustsynchronize this method. Is my logic on this correct? If not can someone explain why I'm wrong?
这没有意义,因为抽象类是子类的定义(契约)。同步方法的抽象定义不需要锁定,孩子需要。所有抽象标题都表明孩子必须同步这个方法。我的逻辑是否正确?如果不是,有人可以解释为什么我错了吗?
回答by Jon Skeet
The comment about not being able to instantiate the abstract class is garbage. Given that it has to be an instance method to be abstract, there certainly isa reference which could be locked on. Concrete methods in abstract classes can still refer to this
. However, that still doesn't mean that abstract classes should be able to be synchronized.
关于无法实例化抽象类的评论是垃圾。鉴于它必须是抽象的实例方法,因此肯定有一个可以锁定的引用。抽象类中的具体方法仍然可以参考this
。然而,这仍然并不意味着抽象类应该能够同步。
Whether or not a method is synchronized is an implementation detailof the method. Synchronization isn't specified anywhereas a declarative contract - it's not like you can synchronize in interfaces, either.
方法是否同步是方法的实现细节。同步并未在任何地方指定为声明性合同 - 您也不能在接口中进行同步。
How a class implements whatever thread safety guarantees it provides is up to it. If an abstract class wants to mandatea particular approach, it should use the template method pattern:
一个类如何实现它提供的任何线程安全保证取决于它。如果一个抽象类想要授权一种特定的方法,它应该使用模板方法模式:
// I hate synchronizing on "this"
private final Object lock = new Object();
public final void foo() {
synchronized(lock) {
fooImpl();
}
}
protected abstract void fooImpl();
That's pretty dangerous in itself though, given that it's effectively calling "unknown" code within a lock, which is a recipe for deadlocks etc.
不过,这本身就非常危险,因为它有效地调用了锁内的“未知”代码,这是死锁等的一个秘诀。
回答by Nathan Hughes
Sorry it doesn't make sense, that's just how it works. Locking behavior can't be specified using abstract methods or interface methods, it's not part of the contract. Probably the idea was that locking behavior is fundamentally part of the implementation -- different implementations will want to perform locking differently -- and it would be overreaching to specify it at that level of abstraction.
对不起,这没有意义,这就是它的工作原理。不能使用抽象方法或接口方法指定锁定行为,它不是契约的一部分。可能的想法是锁定行为从根本上是实现的一部分——不同的实现将希望以不同的方式执行锁定——并且在该抽象级别指定它会过度。
回答by irreputable
synchronized void foo()
{
body
}
is defined to be equivalent to
被定义为等价于
void foo()
{
synchronized(this)
{
body
}
}
(if static, synchronized on the class instead of this
)
(如果是静态的,则在类上同步而不是this
)
Since an abstract method has no body, synchronized
keyword on the method is undefined.
由于抽象方法没有主体,因此synchronized
该方法上的关键字未定义。
回答by Bhesh Gurung
I think one logic behind that could be that whether or not to synchronize that method should be decided by the implementing class. Meaning, it gives the freedom to the implementer to choose on whether to provide a synchronized or unsynchronized implementation. Plus, the client would also have option to to select the unsynchronized version so as to avoid synchronization overhead if thread-safety is not an issue.
我认为这背后的一个逻辑可能是是否同步该方法应该由实现类决定。意思是,它让实现者可以自由选择是提供同步还是非同步实现。另外,如果线程安全不是问题,客户端还可以选择选择未同步的版本以避免同步开销。