Name: skT88420 Date: 11/25/99
java version "1.2"
Classic VM (build JDK-1.2-V, green threads, sunwjit)
According to the Java Language Specification (or more precisely it does not say
anything about this (or I have not found it)) it is OK to override a
synchronized method with a non synchronized one. If this is good or bad might be
discussed, but to exemplify why I think this is bad I'll give you an example.
First we have 3 classes, Thread1, Thread2 and Bar. Both Thread1 and Thread2 have
references to the same Bar instance and they execute the same method repeatedly
in Bar, synchronizedMethod, I.e. Bar looks like this
public class Bar {
public synchronized void synchronizedMethod() {
for (int i=0; i<10; i++) System.out.print(i);
System.out.println();
}
}
This works OK, since synchronizedMethod() is synchronized, and both Thread1 and
Thread2 assume that whenever they use an instance of a Bar method the
synchronizedMethod() is synchronized.
Then we add a 4th class, a subclass to Bar called Foo
public class Foo extends Bar {
public void synchronizedMethod() {
for (int i=0; i<10; i++) System.out.print(i);
System.out.println();
}
}
Now we will have problems if a Foo instance is casted to a Bar instance and this
instance is given to both Thread1 and Thread2. Since Thread1 and Thread2 can not
tell the difference between a Bar and a Foo (since they wrere written before Foo
was ever thought of), they will gladly assume that the Bar instance they are
given is properly synchronized...
Declaring a method as synchronized is like signing a contract, promising that
the method will always be sysnchronized. And if this contract is ever broken,
unexpected/gruelsome consequencies might occur.
One more thing. There is a subtle difference between
public void synchronized foo() { } // 1
and
public void foo() { synchronized(this) { } } // 2
The difference is that in the first case the compiler will mark the synchronized
method with a flag and in the other case it will insert monitorenter/monitorexit
bytecodes. I am only worried about the first case.
This subtle difference makes it very easy for the compiler to issue a warning
whenever the first case is found, and I think that would be *very* good to have
that waring. I don't think you can change the spec without messing up a lot of
code (for instance by enforcing all synchronized methods to stay synchronized
when they are overridden), right?
(Review ID: 98287)
======================================================================