Re: a simple multi-thread question
On 1/26/2015 1:08 PM, Robbie Brown wrote:
On 26/01/15 18:05, Robbie Brown wrote:
On 26/01/15 15:55, Eric Sosman wrote:
On 1/26/2015 10:40 AM, John wrote:
I am amazed at what I saw:
synchronized private void print()
{
System.out.println("printing A");
System.out.println("printing B");
System.out.println("printing C");
}
[... he gets interleaved output ...]
Each Java object has its own lock ("monitor"), independent of the
locks belonging to other Java objects. When you call a synchronized
instance method, Java acquires the lock of the "this" object before
proceeding, and releases it when the method finishes. If there are
several object instances floating around, there are several "this"
and several independent locks.
I thought the method is atomic.
No. Synchronization is not about methods (or code blocks), but
about objects: You lock the *object*, not a method.
Are you sure?
If you have a class with two methods and one (or more) of them is
synchronized and one (or more) isn't then a thread can obtain the lock
on an instance of that class which locks out all other threads from the
synchronized methods but the non synchronized methods of that instance
are still available to other threads.
At least that's how I remember it.
Ooops that should have read "If you have a class with *several* methods
We're both speaking a bit informally, and this is perhaps why we
appear to disagree even if we probably don't. Let me try to be a
little more precise, at the risk of possibly confusing the O.P. to whom
my original informal language was directed:
A method or code block that is synchronized must lock the monitor
of some object instance before starting execution, and must unlock it
on normal or abrupt completion. If the instance's monitor is already
locked by a different thread, the attempt to re-lock it stalls and the
attempting thread waits for a later opportunity.
The monitor is locked and released by code, but it belongs to the
object instance. That implies a couple of things:
- Two different threads can execute the same synchronized method
or code block if they synchronize on different object instances.
(This was the case that surprised the O.P.) If the "this" in
thread T1 is the red object and "this" in T2 is the blue object,
both T1 and T2 can execute `synchronized makeHay()' at the same
time: The red and blue objects' monitors don't interfere.
- Two different threads can get in each other's way by executing
different methods synchronized on the same object instance.
If threads T1 and T2 both have a "this" that refers to the
orange object, then T1 cannot run `synchronized makeHay()'
at the same time that T2 runs `synchronized makeWhoopee()'.
Even though makeHay() and makeWhoopee() are distinct methods,
they cannot run at the same time on the same object.
.... and that's what I meant by synchronization pertaining to objects,
not to code.
You're quite right that synchronization does not interfere with
unsynchronized code. Holding an object's monitor does not prevent all
uses of that object, only those that attempt to lock the same monitor.
If that's what you thought I meant, I didn't and I'm sorry for leading
you astray.
For completeness: Even a static method can be synchronized, even
though there's no "this" object to synchronize on. What happens is
that it synchronizes on its own class' Class object. Thus, all static
synchronized methods of one class lock each other out (which is sort
of what the O.P. was expecting for instance methods), but it's still
not about code blocking code: It's about whether the Class object's
monitor is or isn't already locked.
For even more completeness: When a thread locks an object's
monitor, it prevents *other* threads from locking that monitor. The
thread that already owns the lock can acquire it a second time, or
a third, fourth, ..., time; `synchronized makeHay()' can call
`synchronized makeWhoopee()' without danger of self-deadlock. The
monitor is finally unlocked when the owning thread performs as many
releases as acquisitions, unwrapping as many layers of lock as it
applied. Again, it's the state of the monitor that matters, not the
identity of the code.
--
esosman@comcast-dot-net.invalid
"Don't be afraid of work. Make work afraid of you." -- TLM