我正在阅读一个thread from CodeRanch,说抽象方法无法同步,因为抽象类无法实例化,这意味着无法锁定对象。
这没有意义,因为抽象类是子类的定义(契约)。同步方法的抽象定义不需要锁定,而子进程则需要。所有抽象标题都表明子必须同步此方法。我的逻辑是否正确?如果没有,有人可以解释为什么我错了吗?
答案 0 :(得分:32)
关于无法实例化抽象类的注释是垃圾。鉴于它必须是一个抽象的实例方法,肯定是一个可以锁定的引用。抽象类中的具体方法仍然可以引用this
。但是,这仍然不意味着抽象类应该能够同步。
方法是否同步是该方法的实现细节。没有将任何地方指定为声明性合同 - 它不像你可以在接口中同步。
一个类如何实现它提供的任何线程安全保证取决于它。如果抽象类想要强制特定方法,它应该使用模板方法模式:
// I hate synchronizing on "this"
private final Object lock = new Object();
public final void foo() {
synchronized(lock) {
fooImpl();
}
}
protected abstract void fooImpl();
这本身就很危险,因为它在锁中有效地调用了“未知”代码,这是一个死锁等的配方。
答案 1 :(得分:8)
对不起它没有意义,这就是它的工作原理。无法使用抽象方法或接口方法指定锁定行为,它不是合同的一部分。可能的想法是锁定行为从根本上是实现的一部分 - 不同的实现将希望以不同的方式执行锁定 - 并且在该抽象级别指定它将是过度的。
答案 2 :(得分:4)
synchronized void foo()
{
body
}
定义为等同于
void foo()
{
synchronized(this)
{
body
}
}
(如果是静态的,在课堂上同步而不是this
)
由于抽象方法没有主体,因此方法上的synchronized
关键字未定义。
答案 3 :(得分:3)
我认为背后的一个逻辑可能是,是否要同步该方法应由实现类决定。这意味着,它为实现者提供了选择是否提供同步或不同步实现的自由。此外,客户端还可以选择不同步的版本,以便在线程安全不成问题时避免同步开销。