Integrated: avoid extra park of vthread when using fixed thread pool
Miao Zheng
github.com+20216587+miao-zheng at openjdk.java.net
Mon Aug 30 12:32:42 UTC 2021
On Thu, 26 Aug 2021 07:21:16 GMT, Miao Zheng <github.com+20216587+miao-zheng at openjdk.org> wrote:
> 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();
This pull request has now been integrated.
Changeset: e0453677
Author: miao zheng <emoryzheng at tencent.com>
Committer: Alan Bateman <alanb at openjdk.org>
URL: https://git.openjdk.java.net/loom/commit/e0453677c9340e38a4a7fdc479c8068499fdce47
Stats: 84 lines in 2 files changed: 83 ins; 0 del; 1 mod
avoid extra park of vthread when using fixed thread pool
Reviewed-by: alanb
-------------
PR: https://git.openjdk.java.net/loom/pull/59
More information about the loom-dev
mailing list