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

David Holmes dholmes at openjdk.java.net
Mon Oct 18 02:45:08 UTC 2021


On Thu, 26 Aug 2021 11:00:58 GMT, Miao Zheng <duke at openjdk.java.net> 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();
>
> 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

The header has extra blank lines at the start and end that need to be removed.

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

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


More information about the loom-dev mailing list