> I have a question about Java sychronization. Suppose I have a
> synchronized method M1() which writes to object X and performs other
> operations, and I have an unsynchronized method M2() which also
> writes to object X. In a multithreaded program, will concurrent
> write to object X occur if thread 1 and thread 2 invoke M1() and
> M2() simultaneously? What if both M1() and M2() are synchronized?
The method body (e.g. "writes to object X") is not relevant here.
Synchronization is about obtaining a lock on a synchronization object,
and every object has its own unique such lock. A method declared
"synchronized" always synchronizes on "this", i.e. the object it's
invoked on.
Since m2() is not synchronized, it can always run regardless of any
synchronized methods.
If both methods are declared synchronized, there will be mutual
exclusion *only* if they are syncrhronized on the *same* object.
So assuming synchronized methods m1() and m2(), and two objects x and
y:
MyClass x = new Myclass();
MyClass y = new Myclass();
Then:
x.m1() and x.m2() will run exclusivly (they both synchronize on x)
y.m1() and y.m2() will run exclusivly (they both synchronize on y)
x.m1() or x.m2() and y.m1() or y.m2() can run concurrently (because
they synchronize on different objects)
/gordon

Signature
[ do not email me copies of your followups ]
g o r d o n + n e w s @ b a l d e r 1 3 . s e
Thomas Hawtin - 12 May 2006 16:51 GMT
> The method body (e.g. "writes to object X") is not relevant here.
Yes. There are couple of points to understand.
Firstly, synchronised is not about multiple threads execute the same
piece of code. Two threads can execute the same synchronised method on
different instances concurrently. However, two threads may not execute
concurrently two different synchronised methods on a single instance.
The second point is that the object you decide to use as a lock does not
need to be linked to the variables that are used within the synchronised
block. For instance, instead of using this, sometimes it is preferable
to use a private object as a lock:
class Thing {
private static class Lock { }
private final Object lock = new Lock();
public void myMethod() {
synchronized (lock) {
... do stuff to this ...
}
}
}
The reason I have used an apparently useless nested class for the lock,
is that the class name can appear in, for instance, stack traces. That
class name can then help you track down problems in significant programs
at a later stage.
> Synchronization is about obtaining a lock on a synchronization object,
> and every object has its own unique such lock. A method declared
> "synchronized" always synchronizes on "this", i.e. the object it's
> invoked on.
As a point of pedantry, static methods synchronise on the class'
java.lang.Class object.
Tom Hawtin

Signature
Unemployed English Java programmer
http://jroller.com/page/tackline/