John Mulholland wrote:In a multithreaded application, if methodA() and methodB() can both change the value of a variable X, I can add the synchronized keyword to both methods. Then, when a thread calls synchronized methodA() and acquires the monitor, this prevents another thread from calling synchronized methodB() until the first thread gives up the monitor. The result is that only one of the synchronized methods can access variable X at any given time.
Basically, that's correct but, as Junilu pointed out, variable X will usually be part of a
class whose
state needs to be synchronized.
But say only methodA() can access variable X. In what circumstances would I want to ensure that two threads did not attempt to call methodA() ? Intuitively it feels right that I would want to avoid that but would be interested in
- hearing of any particular examples of when I really should synchronize a single method ?
- does this means that in a multi-threaded application I should synchronize all data access (using synchronized methods/statements)?
Phew. That's a fairly big question because (unfortunately) synchronization applies to both writing
and reading; so a seemingly innocuous thing like
++i, which involves both a read AND a write, can be "interfered with" by unsynchronized attempts to do the same thing, or even just to read the "current state" of
i.
In the absence of synchronization, the
Java compiler is allowed to perform all sorts of optimizations that make code run quicker, like storing values locally and re-ordering instructions (provided they have the same
logical outcome) so, yes, your "intuition" is right: synchronization slows things down, and also makes
testing more complex, so if you can avoid it, it's generally preferable. And even if it's
required (as it sometimes is), you generally want to keep synchronized blocks or methods as short as possible - especially in terms of execution time.
However, without going into all the 'in's and 'out's of the Java memory model, or the intricacies of "happens-before" logic, it's very difficult to give generalizations on HOW
you should do it.
My suggestion would be to start with the
tutorials, and come back if you have a specific question on something you don't follow in there.
I should add that the
synchronized keyword is no longer the sole form of synchronization; and others (eg,
ReentrantLocks) are arguably better; but it's by no means cut-and-dried.
HIH
Winston