posted 22 years ago
When you look at synchronization, pay attention to what objects are the target of the synchronization, and think of a synchronized method as though it its block of code were "synchronized(this)". Here is a crude example that may help illustrate the point.
For example
Suppose we have one instance demo of Demo, and we get the following sequence of calls
Thread A calls demo.define("X"), which runs to completion.
Thread A calls demo.another("X"), and gets pre-empted between the lines marked 1 and 3.
Now thread B executes and calls demo.another("X").
As written, the map would contain X="..".
If we did not include the synchronzed(this) in both define() and another(), then the another() called by thread B could run in the between the lines marked 1 and 3 of thread A's call to "another", resulting in the final value X=".".
In this case, it is important that the body of both methods be explicitly synchronized on the same object, whether it be the Hashtable object or the Demo object; I chose the demo object here. If and only if no other methods of Demo or any other class refer to this hashtable without being synchronized on the same object, then it does not matter whether we used a synchronized collection (e.g., Hashtable) or an unsynchronized collection (e.g., HashArray).
For the purpose of this discussion, I chose to write out that the bodies of the methods are synchronized on this. Of couse, this is equivalent to using the synchronized modifier in the method headers instead.