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

我正在阅读CodeRanch的一个线程,说抽象方法无法同步,因为抽象类无法实例化,这意味着没有要锁定的对象。

这没有意义,因为抽象类是子类的定义(协定)。同步方法的抽象定义不需要锁定,子方法需要锁定。所有抽象标题将指示的是子项必须同步此方法。我的逻辑是否正确?如果不是,有人可以解释为什么我错了吗?


答案 1

关于无法实例化抽象类的注释是垃圾。鉴于它必须一个抽象的实例方法,当然有一个可以锁定的引用。抽象类中的具体方法仍然可以引用 。但是,这仍然并不意味着抽象类应该能够同步。this

方法是否同步是该方法的实现细节。同步没有在任何地方指定为声明性协定 - 它也不是可以在接口中同步。

一个类如何实现它提供的任何线程安全保证取决于它。如果抽象类想要强制使用特定方法,则应使用模板方法模式:

// I hate synchronizing on "this"
private final Object lock = new Object();

public final void foo() {
    synchronized(lock) {
        fooImpl();
    }
}

protected abstract void fooImpl();

这本身就非常危险,因为它有效地调用了锁内的“未知”代码,这是死锁等的秘诀。


答案 2

不应使用抽象方法或接口方法指定锁定行为,因为它不应成为协定的一部分。

这个想法可能是锁定行为从根本上是实现的一部分 - 不同的实现将希望以不同的方式执行锁定 - 并且在该抽象级别指定它将适得其反。

请记住,该关键字专门用于实现隐式锁定(获取调用实例方法的对象上的锁定),并且有一些方法可以使用ReentrantLock等替代方法进行锁定,其中该关键字不适用,或者可能使用CAS或以其他方式完全避免锁定。synchronized


推荐