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) ======================================================================
|