为什么"同步"在多态性中没有作用

时间:2015-07-04 18:36:20

标签: java multithreading synchronization polymorphism

synchronized不是方法签名的一部分。但是当我们覆盖一个方法时,它不仅是方法签名,它决定了被覆盖的方法是否会被编译。

例如,我们无法添加或扩大已检查的异常

为什么synchronized在多态性中没有作用。如果不放synchronized,则不应覆盖synchronized方法。因为使用超类变量的人可能认为所有方法都是线程安全的。

但是,应该允许使用synchronized覆盖非同步方法,因为它会添加更多功能,但另一方面,除了时滞之外,用户不会遇到任何错误。

我正在寻找一个合乎逻辑的解释,它可以为#34;设计如此"。

3 个答案:

答案 0 :(得分:9)

  

A"同步"如果没有放置" synchronized"。

,则不应覆盖该方法

错误。基类可能不是线程安全的,但子类可能有自己的同步,例如锁,无锁线程安全数据结构等。并非所有线程安全方法都是同步的,并非全部synchronized方法是线程安全的。

同样可以朝另一个方向发展(但可能会违反其他原则,视具体情况而定)

synchronized不是一个面向对象的东西,而是一个运行时/执行现象,以及一个实现细节。它所做的全部是acquire a monitor,方式synchronized(this){ }(或者如果是静态的话,在java.lang.Class对象上进行同步)。作为一个实现细节,将它暴露给OOP考虑是没有意义的。

注意:这并不意味着编译时注释(例如@ThreadSafe)没有意义。确实如此,因为它引用了方法的合同是线程安全的。 synchronized没有这样做。

答案 1 :(得分:5)

您可以看到JDK-4294756的解释,但是如果方法在不保留synchronized修饰符的情况下覆盖其他方法,则可以。当一个方法覆盖synchronized方法但没有声明自己synchronized时,此错误报告要求编译器显示警告,并且它已关闭为"赢得&#t; t修复& #34 ;.关键原因如下:

  

使用synchronized修饰符,以及其他同步通道   明确的同步'声明,是执行的一部分   由类表示的抽象,以及捕获的替代实现   在子类中可以使用不同的同步策略   实现等效的语义。作为一个例子,考虑一下a的情况   较小的临界区(受同步的语句保护)   unsynchronized方法替换了一个受其保护的较小方法   整数由同步方法修饰符。

因此缺少synchronized修饰符并不一定意味着该方法不是线程安全的。线程安全可以在方法中细化。

答案 2 :(得分:1)

让我用不同的方式:

假设我们有两个类:

class Foo {
    public synchronized void doSomething(...) { ... }
}

class Bar extends Foo {
    public void doSomething(...) { ... }
}

FooBar不同的类。 foo.doSomething(...)bar.doSomething(...)是不同的方法。

synchronized关键字不适合调用者的利益:它没有说明foo.doSomething(...) 做什么synchronized关键字只是该方法实施的详细信息。

Foo类需要同步其doSomething(...)方法才能在多线程环境中正确履行其API协定。 bar.doSomething(...)方法的实现方式不同,并且不需要同步。

只要Bar实例可以在需要Foo实例的地方使用,每个人都应该感到高兴。调用者没有理由要求同步方法:调用者应该只希望方法工作