synchronize section does not (always) block!
David Holmes
David.Holmes at oracle.com
Tue Jul 13 22:45:29 PDT 2010
Eduard Wirch said the following on 07/13/10 22:03:
> java version "1.6.0_19"
> Java(TM) SE Runtime Environment (build 1.6.0_19-b04)
> Java HotSpot(TM) 64-Bit Server VM (build 16.2-b04, mixed mode)
Okay that's recent enough not to have the issue I was thinking of, and
in any case that was a different issue (incorrectly reporting
waiting-to-lock when already locked).
Do you have a complete test case that shows this? Does the system hang
(else how did you happen to grab a thread dump at just the right moment
to see this)?
What does the code in SomeOtherClass look like? It is that code which
appears to have locked the object in dispute, and both threads are then
blocked trying to acquire different monitors.
Like Chris I tend to suspect the error is in the thread dump rather than
the actual synchronization code, but I can't see anything obvious where
it might appear that two threads claim to own the same monitor (one of
the threads will have just released it). That said finding the code
where the owned monitors is set/cleared in the frame is non-trivial for
a non-compiler guy like myself :)
David Holmes
>
> Regards,
> Eduard
>
> -----Ursprüngliche Nachricht-----
> Von: hotspot-dev-bounces at openjdk.java.net [mailto:hotspot-dev-bounces at openjdk.java.net] Im Auftrag von David Holmes
> Gesendet: Dienstag, 13. Juli 2010 13:42
> An: hotspot-dev at openjdk.java.net
> Betreff: Re: synchronize section does not (always) block!
>
> Sorry mis-read the details. Which version of the VM is this? There was a bug
> where the thread dump showed the wrong locked monitor.
>
> David Holmes
>
> On 13/07/2010 9:21 PM, Eduard Wirch wrote:
>> Hi
>>
>>
>> I've noticed something very strange yesterday. It seems that in app two threads are entering two synchronized blocks locking on the same object at the same time.
>>
>> The class (MyClass) containing the relevant code looks similar to this:
>>
>> ------------------------------------------------------------------
>> private static int[] myLock = new int[0];
>>
>> protected static int methodA(final long handle, final byte[] sort) {
>> synchronized (myLock) {
>> return xsMethodA(handle, sort);
>> }
>> }
>>
>> protected static int methodB(final long handle) {
>> synchronized (myLock) {
>> return xsMethodB(handle);
>> }
>> }
>> ------------------------------------------------------------------
>>
>>
>>
>> I created a thread dump of my application running the above class and was very surprised as I saw this:
>>
>> ------------------------------------------------------------------
>> "http-8080-136" daemon prio=10 tid=0x00000000447df000 nid=0x70ed waiting for monitor entry [0x00007fd862aea000]
>> java.lang.Thread.State: BLOCKED (on object monitor)
>> at com.MyClass.methodA(MyClass.java:750)
>> - locked<0x00007fd8a6b8c790> (a [I)
>> at com.SomeOtherClass.otherMethod(SomeOtherClass.java:226)
>> ...
>>
>> "http-8080-111" daemon prio=10 tid=0x00007fd87d1a0000 nid=0x70c8 waiting for monitor entry [0x00007fd86e15f000]
>> java.lang.Thread.State: BLOCKED (on object monitor)
>> at com.MyClass.methodB(MyClass.java:991)
>> - locked<0x00007fd8a6b8c790> (a [I)
>> at com.SomeOtherClass.yetAnotherMethod(SomeOtherClass.java:3231)
>> ...
>>
>> "http-8080-146" daemon prio=10 tid=0x00007fd786dab000 nid=0x184b waiting for monitor entry [0x00007fd8393b6000]
>> java.lang.Thread.State: BLOCKED (on object monitor)
>> at com.MyClass.methodC(MyClass.java:750)
>> - waiting to lock<0x00007fd8a6b8c790> (a [I)
>> at com.SomeOtherClass.yetAnoterMethod2(SomeOtherClass.java:226)
>> ...
>> (43 more threads waiting for the lock)
>> ------------------------------------------------------------------
>>
>> (I changed the class and method names for the case of simplicity, so don't get confused by the silly names.)
>>
>>
>> It seems that thread http-8080-136 and http-8080-111 have both acquired the lock on myLock. It is the same object as the object address is the same: 0x00007fd8a6b8c790.
>>
>> The Java Runtime Specification says this about the synchronized keyword:
>> ------------------------------------------------------------------
>> A synchronized statement acquires a mutual-exclusion lock (§17.1) on behalf of the executing thread, executes a block, then releases the lock. While the executing thread owns the lock, no other thread may acquire the lock. [The Java Language Specification, 14.19]
>> ------------------------------------------------------------------
>>
>> So how is this even possible?
>>
>>
>> Regards,
>> Eduard
>>
More information about the hotspot-dev
mailing list