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?
-
possible duplicate of Overriding a synchronized methodRaedwald– Raedwald2013-04-15 12:07:48 +00:00Commented Apr 15, 2013 at 12:07
Add a comment
|
3 Answers
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).
3 Comments
mrec
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.Grim
Will calling
super.draw() be still synchronized?8192K
If
super.draw() is synchronised, then of course it will.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.
4 Comments
ratchet freak
easier way to test would be to test on
Thread.holdsLock(this); in the overridden methoduser207421
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.
Timo
@EJP At first I thought you were wrong. Then I realized you were actually right, but rather pessimistic...
JBM
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.