7 Replies Latest reply: Mar 24, 2010 9:34 AM by 807580 RSS

    How can multiple threads hold the same lock?

    807580
      I was always under the impression that no 2 threads could hold a lock for the same object, and yet the HotSpot traces say this is happening all the time.

      For example Object 0x0a6c1bf8 is locked in 2 threads:

      "10.129.24.35-1" daemon prio=6 tid=0x2836bad0 nid=0x9d4 runnable [0x2b28f000..0x2b28fc9c]
      at java.net.PlainSocketImpl.socketConnect(Native Method)
      at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)
      - locked <0x2493f6e0> (a java.net.SocksSocketImpl)
      at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195)
      at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182)
      at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)
      at java.net.Socket.connect(Socket.java:519)
      at org.jacorb.orb.factory.PortRangeSocketFactory.doCreateSocket(PortRangeSocketFactory.java:142)
      at org.jacorb.orb.factory.AbstractSocketFactory.createSocket(AbstractSocketFactory.java:54)
      at org.jacorb.orb.iiop.ClientIIOPConnection.createSocket(ClientIIOPConnection.java:313)
      at org.jacorb.orb.iiop.ClientIIOPConnection.connect(ClientIIOPConnection.java:160)
      - locked <0x0a6c1b98> (a org.jacorb.orb.iiop.ClientIIOPConnection)
      at org.jacorb.orb.giop.GIOPConnection.sendMessage(GIOPConnection.java:934)
      - locked <0x0a6c1bf8> (a java.lang.Object)
      at org.jacorb.orb.giop.GIOPConnection.sendRequest(GIOPConnection.java:900)
      at org.jacorb.orb.giop.ClientConnection.sendRequest(ClientConnection.java:323)
      at org.jacorb.orb.giop.ClientConnection.sendRequest(ClientConnection.java:304)
      at org.jacorb.orb.Delegate.invoke_internal(Delegate.java:1024)
      - locked <0x0d434a88> (a java.lang.Object)
      at org.jacorb.orb.Delegate.invoke(Delegate.java:939)
      at org.omg.CORBA.portable.ObjectImpl._invoke(ObjectImpl.java:80)
      at com.company.MyApp._StateChangeListenerStub.newChanges(_StateChangeListenerStub.java:33)
      at com.company.MyAppManager.ListenerOneway.send(ListenerOneway.java:65)
      at com.company.MyAppManager.Sender.run(Sender.java:139)

      "ClientMessageReceptor840" daemon prio=6 tid=0x2a3ab988 nid=0x6b4 in Object.wait() [0x2f70f000..0x2f70fb1c]
      at java.lang.Object.wait(Native Method)
      at java.lang.Object.wait(Object.java:474)
      at org.jacorb.orb.giop.GIOPConnection.waitUntilConnected(GIOPConnection.java:278)
      - locked <0x0a6c1bf8> (a java.lang.Object)
      at org.jacorb.orb.giop.GIOPConnection.getMessage(GIOPConnection.java:318)
      at org.jacorb.orb.giop.GIOPConnection.receiveMessages(GIOPConnection.java:464)
      at org.jacorb.orb.giop.MessageReceptor.doWork(MessageReceptor.java:71)
      at org.jacorb.util.threadpool.ConsumerTie.run(ConsumerTie.java:61)
      at java.lang.Thread.run(Thread.java:595)

      Have I miss-interpreted the HotSpot stack trace?
        • 1. Re: How can multiple threads hold the same lock?
          JoachimSauer
          Note that the second thread called wait() on some object (most likely on 0x0a6c1bf8), so it had to ["release ownership of this monitor"|http://java.sun.com/javase/6/docs/api/java/lang/Object.html#wait()].
          • 2. Re: How can multiple threads hold the same lock?
            807580
            Hello David,

            yes, you are misinterpreting the stack traces. When a thread acquires the lock for an object x and then waits on it, it releases the lock. If it did not, no other thread would ever be able to take it and signal the original thread to continue. However, when another thread does so, the thread can not continue until the lock was released by the signaling thread. So the same lock is never held by two threads.

            With kind regards
            Ben
            • 3. Re: How can multiple threads hold the same lock?
              807580
              So the HotSpot is miss-leading. "ClientMessageReceptor840" is "waiting for monitor" trying to get the lock to proceed. Whereas "10.129.24.35-1" has the lock and is running inside the monitor.
              Is this right or is it more subtle than this.
              • 4. Re: How can multiple threads hold the same lock?
                JoachimSauer
                davidnewcomb wrote:
                So the HotSpot is miss-leading. "ClientMessageReceptor840" is "waiting for monitor" trying to get the lock to proceed.
                No, that thread is waiting for a "notify()" on that object before it can finish the wait() method. Only after it received that, will it need to re-acquire the lock.
                Whereas "10.129.24.35-1" has the lock and is running inside the monitor.
                Yes.
                • 5. Re: How can multiple threads hold the same lock?
                  807580
                  So they are both in a synchronized block on the same mutex/Object, but one is in a wait and one isn't?
                  • 6. Re: How can multiple threads hold the same lock?
                    JoachimSauer
                    davidnewcomb wrote:
                    So they are both in a synchronized block on the same mutex/Object, but one is in a wait and one isn't?
                    Yes, they both synchronized on the same object, but only one of them holds the objects monitor, since the other one is wait()-ing on that object.
                    • 7. Re: How can multiple threads hold the same lock?
                      807580
                      To summarise they are both in a synchronized block on the same mutex/Object, but one is in a wait and one isn't.

                      So then it follows that if the HotSpot thread reads " - waiting on <address>" like:

                      "SomeThread" daemon prio=6 tid=0x29a06658 nid=0xf28 in Object.wait() [0x2b18f000..0x2b18fa1c]
                      at java.lang.Object.wait(Native Method)
                      - waiting on <address> (a javax.swing.TimerQueue)
                      at com.comp.SomeThread.run(TimerQueue.java:236)
                      - locked <0x09539510> (a javax.swing.TimerQueue)
                      at java.lang.Thread.run(Thread.java:595)

                      then it means that the thread is trying to enter the synchronized block on the same mutex/Object but it can't because there is another thread in there which is running, so it is waiting on the outside of the lock instead of the inside of the lock like "ClientMessageReceptor840".

                      Ok, I think I get it now. Thanks everyone for your help.