synchronize section does not (always) block!

Christopher Phillips Christopher.Phillips at oracle.com
Tue Jul 13 05:33:05 PDT 2010


  Hi Eduard
I think its the thread dump that is misleading.
If you really think that the 2 are in the lock simultaneously you
should probably get a gcore (which is externally consistent).
The state you see "waiting for monitor entry" is actually MONITOR_WAIT
which can represent the following code  before actual acquisition of
a hot lock :
(also see OSThreadContendState in osThread.hpp)
called from:
src/share/vm/runtime/synchronizer.cpp

   3413      OSThreadContendState osts(Self->osthread());
   3414      ThreadBlockInVM tbivm(jt);
   3415
   3416      Self->set_current_pending_monitor(this);
   3417
   3418      // TODO-FIXME: change the following for(;;) loop to 
straight-line code.
   3419      for (;;) {
   3420        jt->set_suspend_equivalent();
   3421        // cleared by handle_special_suspend_equivalent_condition()
   3422        // or java_suspend_self()
   3423
   3424        EnterI (THREAD) ;
   3425
   3426        if (!ExitSuspendEquivalent(jt)) break ;
   3427
   3428        //
   3429        // We have acquired the contended monitor, but while we were
   3430        // waiting another thread suspended us. We don't want to 
enter
   3431        // the monitor while suspended because that would 
surprise the
   3432        // thread that suspended us.



Chris

On 13/07/10 08:03 AM, Eduard Wirch wrote:
> Hi David
>
>
> 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)
>
>
> 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
>>


-- 
--
--     Woda: "Java: write once, debug anywhere" Hong Zhang
                      http://thehenrys.ca
  | Chris Phillips - Oracle Java Sustaining JVM Engineer,          |
  | mailto:Christopher.Phillips at Oracle.Com      (416)483-3768      |
  |        WhoZat?                                                 |
  | http://LGonQn.Org/www/Chris.Phillips  cell: (416)505-3610      |
  "EPIC stands for Expects Perfectly Intuitive Compilers" P. Bannon
                   http://www.hazmatmodine.com
  NOTICE:
  This email message is for the sole use of the intended recipient(s)
  and may contain confidential and privileged information.  Any
  unauthorized review, use, disclosure or distribution is prohibited.
  If you are not the intended recipient, please contact the sender by
  reply email and destroy all copies of the original message.
                    "blah blah blah - Ginger!"
--



More information about the hotspot-dev mailing list