web-dev-qa-db-ja.com

同期はJavaで継承されますか?

スーパークラスPointsynchronizedメソッドdraw()があります。 Pointのサブクラスはメソッドdraw()をオーバーライドした場合、または常にそれを記述しなければならない場合、synchronizedを継承しますか?

30
Yoda

いいえ、常にsynchronizedと書く必要があります。スーパークラスの同期メソッドを呼び出す場合、これはもちろん同期呼び出しになります。 synchronizedはメソッドシグネチャの一部ではありません。

Doug Leaからの詳細な説明については、 http://gee.cs.oswego.edu/dl/cpj/mechanics.html を参照してください。Javaスレッドボス(またはそう) 。

29
Sebastian

これを書くことによってあなた自身でそれをチェックすることができます:

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

    }
}

私のマシンでは、200000ではなく137099でした。

10
rarry

オーバーライドしてsynchronizedを削除すると、オーバーライドされたメソッドは同期されなくなります。見つかりました ここ および ここ

4
Simulant