RFR: avoid extra park of vthread when using fixed thread pool [v2]

Miao Zheng github.com+20216587+miao-zheng at openjdk.java.net
Thu Aug 26 11:00:58 UTC 2021


> The test case of ParkWithFixedThreadPool.java create 300 virtual threads, each vthread(exclude latest vthread) park itself and unpark previous vthread. The expected result is any vthread can finish.
> 
> Running this test case in slowdebug and the test will random hang.
> 
> There are three vthreads which are vt-1, vt-2, vt-3;
> (1) vt-1 take the ReentrantLock, and vt-2 try to unpark vt-1, and vt-2 fail to get ReentrantLock so it park itself( the call stack is shown below); 
> (2)vt-3 unpark vt-2, and vt-2 try to get ReentrantLock again, but the ReentrantLock is still owned by vt-1, vt-2 park itself again;
> (3)vt-1 release the ReentrantLock and unpark vt-2, vt-2 park itself at ParkWithFixedThreadPool.java:55, and it will never unpark.(because the unpark from vt-3 has consumed)
> 
> The reason is scheduler.execute() will try to alloc a Reentrant lock when using fix thread pool, the call stack is like:
>     at java.lang.VirtualThread.tryPark(VirtualThread.java:472)
>     at java.lang.VirtualThread.park(VirtualThread.java:424)
>     at java.lang.System$2.parkVirtualThread(System.java:1279)
>     at sun.misc.VirtualThreads.park(VirtualThreads.java:56)
>     at java.util.concurrent.locks.LockSupport.park(LockSupport.java:183)
>     at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)
>     at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:870)
>     at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1199)
>     at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:209)
>     at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:285)
>     at java.util.concurrent.LinkedBlockingQueue.offer(LinkedBlockingQueue.java:418)
>     at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1371)
>     at java.lang.VirtualThread.unpark(VirtualThread.java:502)
>     at java.lang.System$2.unparkVirtualThread(System.java:1287)
>     at sun.misc.VirtualThreads.unpark(VirtualThreads.java:70)
>     at ParkWithFixedThreadPool$1.run(ParkWithFixedThreadPool.java:51)
> 
> 
> The solution is switch back to carrier thread before call scheduler.execute();

Miao Zheng has refreshed the contents of this pull request, and previous commits have been removed. The incremental views will show differences compared to the previous content of the PR. The pull request contains one new commit since the last revision:

  avoid extra park of vthread when using fixed thread pool

-------------

Changes:
  - all: https://git.openjdk.java.net/loom/pull/59/files
  - new: https://git.openjdk.java.net/loom/pull/59/files/6654bfe6..b08d720f

Webrevs:
 - full: https://webrevs.openjdk.java.net/?repo=loom&pr=59&range=01
 - incr: https://webrevs.openjdk.java.net/?repo=loom&pr=59&range=00-01

  Stats: 73 lines in 2 files changed: 21 ins; 33 del; 19 mod
  Patch: https://git.openjdk.java.net/loom/pull/59.diff
  Fetch: git fetch https://git.openjdk.java.net/loom pull/59/head:pull/59

PR: https://git.openjdk.java.net/loom/pull/59


More information about the loom-dev mailing list