The deadlock detection is based on traditional exclusive locks,<br>where a lock can only have one locker.<br><br>I think the behavior can be understood by thinking about how<br>the libraries communicate their state to hotspot.<br>
- whenever a lock is acquired _exclusively_ <br>  AbstractOwnableSynchronizer<br>- whenever a thread is waiting to acquire a lock.<br>  LockSupport.park(lockObject)<br><br>In the case of T1 holding the read lock while T2 tries to acquire<br>
the write lock,  hotspot is aware of T2&#39;s state, <br>but is not notified that T1 is  preventing it.<br><br>Fixing this would require revisiting the monitoring model,<br>which is unlikely to happen.<br><br>Martin<br><br>
<div class="gmail_quote">On Fri, Jun 26, 2009 at 07:13, Sam Berlin <span dir="ltr">&lt;<a href="mailto:sberlin@gmail.com">sberlin@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
There seem to be some classic scenarios of deadlock where the VM doesn&#39;t detect deadlock.  With the following two threads:<br><br>   new Thread(new Runnable() {  // Thread 1<br>            @Override<br>            public void run() {<br>

                System.out.println(&quot;t1 locking a&quot;);<br>                a.lock();<br>                try {<br>                    System.out.println(&quot;t1 locked a&quot;);<br>                    try {Thread.sleep(1000); } catch(Exception e) {}<br>

                    System.out.println(&quot;t1 locking b&quot;);<br>                    b.lock();<br>                    try {<br>                        System.out.println(&quot;t1 locked b&quot;);<br>                        try {Thread.sleep(100000); } catch(Exception e) {}<br>

                    } finally {<br>                        b.unlock();<br>                    }<br>                } finally {<br>                    a.unlock();<br>                }<br>            }<br>        }).start();<br>

        <br>        new Thread(new Runnable() {  // Thread 2<br>            @Override<br>            public void run() {<br>                System.out.println(&quot;t2 locking b&quot;);<br>                b.lock();<br>                try {<br>

                    System.out.println(&quot;t2 locked b&quot;);<br>                    System.out.println(&quot;t2 locking a&quot;);<br>                    a.lock();<br>                    try {<br>                        System.out.println(&quot;t2 locked a&quot;);<br>

                        try {Thread.sleep(100000); } catch(Exception e) {}<br>                    } finally {<br>                        a.unlock();<br>                    }<br>                } finally {<br>                    b.unlock();<br>

                }<br>            }<br>        }).start();<br><br>This prints out:<br> t1 locking a<br> t1 locked a<br> t2 locking b<br> t2 locked b<br> t2 locking a<br> t1 locking b<br> [and flow halts because of deadlock]<br>

<br>In the simple case of &#39;a&#39; and &#39;b&#39; being simple ReentrantLocks (or Objects and using synchronize()), the VM correctly finds a deadlock.  If &#39;a&#39; and &#39;b&#39; are ReentrantReadWriteLocks, there are some conditions where it will not find a deadlock.<br>

<br>Here&#39;s the possible deadlocking scenarios and the result:<br>  Thread 1 &amp; Thread 2 all lock writeLock ---&gt; VM finds deadlock<br>  Thread 1 locks all writeLocks, Thread 2 &#39;b&#39; locks writeLock, &#39;a&#39; locks readLock --&gt; VM finds deadlock<br>

  Thread 1 locks all writeLocks, Thread 2 &#39;b&#39; locks readLock , &#39;a&#39; locks writeLock--&gt; NO DEADLOCK FOUND<br>  Thread 1 locks all writeLocks, Thread 2 locks all readLocks --&gt; NO DEADLOCK FOUND <br>  Thread 1 &#39;a&#39; locks writeLock, &#39;b&#39; locks readLock, Thread 2 locks all writeLocks --&gt; VM Finds deadlock<br>

  Thread 1 &#39;a&#39; locks readLock, &#39;b&#39; locks writeLock, Thread 2 locks all writeLocks --&gt; NO DEADLOCK FOUND<br>  Thread 1 locks all readLocks, Thread 2 locks all writeLocks --&gt; NO DEADLOCK FOUND<br>  Thread 1 &#39;a&#39; locks writeLock, &#39;b&#39; locks readLock, Thread 2 &#39;b&#39; locks writeLock, &#39;a&#39; locks readLock --&gt; VM finds deadlock<br>

  Thread 1 &#39;a&#39; locks readLock, &#39;b&#39; locks writeLock, Thread 2 &#39;b&#39; locks readLock, &#39;a&#39; locks writeLock --&gt; NO DEADLOCK FOUND<br><br>The pattern seems to be that whenever a deadlock would be encountered due to out-of-order locking, if the readLock was locked before a deadlock-inducing writeLock, then no deadlock is found.  Conversely, if the writeLock is locked before the deadlock-inducing readLock, the VM does find deadlock.<br>

<br>This is with JDK 1.6.0_12-b04.<br><br>Is this a known issue, a bug, or something else?<br><br>Thanks much,<br><font color="#888888"> Sam<br><br><br>
</font><br>_______________________________________________<br>
Concurrency-interest mailing list<br>
<a href="mailto:Concurrency-interest@cs.oswego.edu">Concurrency-interest@cs.oswego.edu</a><br>
<a href="http://cs.oswego.edu/mailman/listinfo/concurrency-interest" target="_blank">http://cs.oswego.edu/mailman/listinfo/concurrency-interest</a><br>
<br></blockquote></div><br>