为什么抽象方法不能同步?

时间:2012-10-09 17:57:03

标签: java multithreading inheritance synchronized abstraction

我正在阅读一个thread from CodeRanch,说抽象方法无法同步,因为抽象类无法实例化,这意味着无法锁定对象。

这没有意义,因为抽象类是子类的定义(契约)。同步方法的抽象定义不需要锁定,而子进程则需要。所有抽象标题都表明子必须同步此方法。我的逻辑是否正确?如果没有,有人可以解释为什么我错了吗?

4 个答案:

答案 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)

我认为背后的一个逻辑可能是,是否要同步该方法应由实现类决定。这意味着,它为实现者提供了选择是否提供同步或不同步实现的自由。此外,客户端还可以选择不同步的版本,以便在线程安全不成问题时避免同步开销。