33

I have superclass Point and a synchronized method draw(). Will the subclasses of Point inherit synchronized if I override method draw() in them or I have to always write it?

Koterpillar
  • 7,883
  • 2
  • 25
  • 41
Yoda
  • 17,363
  • 67
  • 204
  • 344
  • possible duplicate of [Overriding a synchronized method](http://stackoverflow.com/questions/10173345/overriding-a-synchronized-method) – Raedwald Apr 15 '13 at 12:07

3 Answers3

32

No, you will always have to write synchronized. If you call the synchronized method of the super class this will of course be a synchronized call. synchronized is not part of the method signature.

See http://gee.cs.oswego.edu/dl/cpj/mechanics.html for detailed description from Doug Lea, Java threading boss (or so).

Sebastian
  • 5,177
  • 4
  • 30
  • 47
  • 4
    Maybe clarify one detail: whether or not a given method call is synchronized depends on the dynamic type of the object it's called on, not the static type. That is, if `foo()` is `synchronized` in `Derived` but not in `Base`, and you assign a `Derived` to a `Base` variable and call `foo()` on it, that call will be synchronized. This point is implicit in 8.4.3.6 of the language spec (which says a `synchronized` method is equivalent to a `synchronized` statement within that method), but I couldn't find it spelled out anywhere else. Runnable demo [here](http://runnable.com/U4zBThIj5WNju2g2/). – mrec Jun 02 '14 at 18:35
  • Will calling `super.draw()` be still synchronized? – Grim Jul 23 '23 at 12:26
  • If `super.draw()` is synchronised, then of course it will. – Sebastian Jul 24 '23 at 13:03
8

You can check it yourself by writing this:

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;
    }
}

And test class

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

    }
}

On my machine it was 137099 instead of 200000.

rarry
  • 3,553
  • 20
  • 23
  • 3
    easier way to test would be to test on [`Thread.holdsLock(this);`](http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html#holdsLock%28java.lang.Object%29) in the overridden method – ratchet freak Apr 14 '13 at 21:33
  • 7
    Doesn't answer the question. Test code could just expose a bug or a time anomaly due to something other than synchronization. The answer is to be found in the language specification. – user207421 Apr 15 '13 at 00:46
  • @EJP At first I thought you were wrong. Then I realized you were actually right, but rather pessimistic... – Timo Sep 13 '13 at 12:10
  • I seriously discourage anyone from exploring like this. Your test might be correct in most cases but miss a very specific but very important aspect - and you'd never know until it bites you. Instead, **READ THE SPECIFICATION!** - then you *know*. – JBM Jul 09 '20 at 14:13
5

your Overriden method will no longer be synchronized if you Override it and remove the synchronized. Found it here and here

Community
  • 1
  • 1
Simulant
  • 19,190
  • 8
  • 63
  • 98