<div>Hello everyone,<br /><br />A day ago <strong>sidknot17</strong> reddit user created a post on reddit <a href="https://www.reddit.com/r/java/comments/1512xuo/virtual_threads_interesting_deadlock/" rel="noopener noreferrer" target="_blank">https://www.reddit.com/r/java/comments/1512xuo/virtual_threads_interesting_deadlock/</a> I still cannot understand, whether it is bug, or not. Maybe someone can help me with it?</div><div> </div><div>So, we have the following code (it is copied from reddit):</div><div><pre><code>for (int i = 0; i < NUMBER_OF_CORES + 1; i++) {
    Thread.startVirtualThread(() -> {
      System.out.println(Thread.currentThread() + ": Before synchronized block");
      synchronized (Main.class) {
            System.out.println(Thread.currentThread() + ": Inside synchronized block");
      }
    });
}</code></pre><div> </div><div><code>I can reproduce deadlock in every 3-d run, using </code>Macbook pro with M1 pro. For me, <code>NUMBER_OF_CORES is <strong>10</strong>. </code></div><div> </div><div><code>Via debugger, I see the following state. We have <strong>10 platform</strong> </code><strong>threads</strong><code> in </code>defaultForkJoinPool (because I have <strong>10 CPU</strong>). Also, this test creates <strong>11 virtual</strong> <strong>threads</strong>.</div><div> </div><div><em>Virtual threads</em> have the following internal state field value:</div><ol><li>9 <em>virtual</em> threads have <strong>(RUNNING  = 3; runnable-mounted), </strong>and their stack trace is finished on <em>synchronized (Main.class)</em>.</li><li><em>1 virtual thread</em> has <strong>(PINNED   = 6; mounted)</strong>, and its stack trace is on line with the <em>second</em> <code>System.out.println.</code></li><li><code><em>1 virtual thread</em> has </code><strong>(RUNNABLE = 2; runnable-unmounted)</strong>, and its stack trace in on line with the <em>first</em> <code>System.out.println</code>.</li></ol><div>Platform threads have the following state:</div><ol><li><em>9 platform threads</em> have <strong>BLOCKED</strong>, and they stack trace is finished on <a href="https://github.com/openjdk/jdk/blob/e73796879299c6170b63edb998439db4764ceae0/src/java.base/share/classes/jdk/internal/vm/Continuation.java#L251" rel="noopener noreferrer" target="_blank">https://github.com/openjdk/jdk/blob/e73796879299c6170b63edb998439db4764ceae0/src/java.base/share/classes/jdk/internal/vm/Continuation.java#L251</a> - <em>if (isStarted()) { enterSpecial(this, true</em></li><li><em>1 platform thread </em>has <strong>WAITING</strong> state, and its stack trace is finished on <a href="https://github.com/openjdk/jdk/blob/e73796879299c6170b63edb998439db4764ceae0/src/java.base/share/classes/jdk/internal/vm/Continuation.java#L248" rel="noopener noreferrer" target="_blank">https://github.com/openjdk/jdk/blob/e73796879299c6170b63edb998439db4764ceae0/src/java.base/share/classes/jdk/internal/vm/Continuation.java#L248</a> - <em>if (!isStarted()) { enterSpecial(this, false</em></li><li>I ran the program with <em>-Djdk.tracePinnedThreads=full</em>, and only one thread was pinned.</li></ol></div><div>So, I don't understand, why do we have deadlock. As we see, many threads are not pinned, so I would expect, that we shouldn't have any deadlocks here.</div><div> </div><div> </div><div> </div><div> </div>