【问题标题】:Is synchronized inherited in Java?Java中是否继承了同步?
【发布时间】:2013-04-06 13:45:16
【问题描述】:

我有超类Pointsynchronized 方法draw()Point 的子类是否会继承 synchronized 如果我在其中重写方法 draw() 或者我必须始终编写它?

【问题讨论】:

标签: java inheritance synchronized


【解决方案1】:

不,你总是要写synchronized。如果你调用超类的同步方法,这当然是一个同步调用。 synchronized 不是方法签名的一部分。

请参阅http://gee.cs.oswego.edu/dl/cpj/mechanics.html,了解来自 Java 线程老板(左右)Doug Lea 的详细描述。

【讨论】:

  • 也许澄清一个细节:给定的方法调用是否同步取决于调用它的对象的动态类型,而不是静态类型。也就是说,如果foo()Derived 中是synchronized 而不是在Base 中,并且您将Derived 分配给Base 变量并在其上调用foo(),则该调用将被同步。这一点隐含在语言规范的 8.4.3.6 中(其中说 synchronized 方法等同于该方法中的 synchronized 语句),但我在其他任何地方都找不到它的拼写。可运行演示here.
【解决方案2】:

您可以通过编写以下代码自行检查:

public class Shape {

    protected int sum = 0;

    public synchronized void add(int x) {
        sum += x;
    }
}


public class Point extends Shape{

    public void add(int x) {
        sum += x;
    }

    public int getSum() {
        return sum;
    }
}

和测试类

public class TestShapes {

    public final static int ITERATIONS = 100000;

    public static void main(String[] args) throws InterruptedException {

        final Point p = new Point();

        Thread t1 = new Thread(){
            @Override
            public void run() {

                for(int i=0; i< ITERATIONS; i++){
                    p.add(1);
                }
            }
        };

        Thread t2 = new Thread(){
            @Override
            public void run() {

                for(int i=0; i< ITERATIONS; i++){
                    p.add(1);
                }
            }
        };

        t1.start();
        t2.start();

        t1.join();
        t2.join();


        System.out.println(p.getSum()); // should equal 200000

    }
}

在我的机器上是 137099 而不是 200000。

【讨论】:

  • 更简单的测试方法是在覆盖方法中测试Thread.holdsLock(this);
  • 不回答问题。由于同步以外的原因,测试代码可能会暴露错误或时间异常。答案可以在语言规范中找到。
  • @EJP 起初我以为你错了。然后我意识到你实际上是对的,但相当悲观......
  • 我严重劝阻任何人不要进行这样的探索。在大多数情况下,您的测试可能是正确的,但会遗漏一个非常具体但非常重要的方面——除非它咬到你,否则你永远不会知道。相反,阅读规范! - 然后你知道
【解决方案3】:

如果您 Override 并删除 synchronized,您的 Overriden 方法将不再同步。找到它herehere

【讨论】:

  • 您的引文都不是规范性参考。
猜你喜欢
  • 2017-12-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-09
  • 1970-01-01
  • 2010-10-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多