Significant degradation of Thread.sleep with virtual threads in JDK 25 vs JDK 21

Attila Kelemen attila.kelemen85 at gmail.com
Sat Nov 22 09:26:57 UTC 2025


Does it have to be Thread.sleep(1) or is even Thread.yield() slow?

Attila

Fredriksson, Christian <christian.fredriksson.2 at volvocars.com> ezt írta
(időpont: 2025. nov. 21., P, 18:52):

> Hey,
>
>
>
> I believe I have found a bug with JDK 25 and virtual threads, but will
> need some guidance in what information I need to provide in order to file a
> bug.
>
>
>
> Short version: after changing from JDK 21 to JDK 25, doing Thread.sleep(1)
> in a virtual thread now sometimes takes up to 60 seconds (!).
>
>
>
> Long version:
>
>
>
> I recently updated an application from Java 21 to 25 and started seeing a
> very negative performance impact.
>
>
>
> The application in question runs ca 20 long running virtual threads which
> basically does the following:
>
>
>
> while (true) {
>
>     doTrivialWork();
>
>     Thread.sleep(1);
>
>     semaphore.acquire();
>
> }
>
>
>
> I.e. do trivial work, sleep 1 ms, wait on a semaphore to be woken by
> another thread, and then loop again. After long investigation I finally
> realized that it was the Thread.sleep that sometimes took significantly
> longer with Java 25 than Java 21.
>
> So I timed it, basically just this:
>
>
>
> while (true) {
>
>     doTrivialWork();
>
>     var start = System.nanoTime();
>
>     Thread.sleep(1);
>
>     var end = System.nanoTime();
>
>     System.out.println("delay=" + (end - start));
>
>     semaphore.acquire();
>
> }
>
>
>
> And let it run >1 million times.
>
>
>
> With JDK 21 and either virtual threads or platform threads, or with latest
> JDK 25 and platform threads, it works fine and the Thread.sleep(1) finishes
> according to the following:
>
>
>
> 99,5% finish within 2 ms
>
> 0,4% finish within 4 ms
>
> Worst case 80 ms
>
>
>
> But with latest JDK 25 and virtual threads, it’s significantly worse:
>
>
>
> 98,0% finish within 2 ms
>
> 0,3% finish within 4 ms
>
> 0,5% taking over 1000 ms
>
> A few hundred occurrences over 60 seconds (!)
>
>
>
> The only change between these runs is JDK version and platform vs virtual
> threads.
>
>
>
> Increasing jdk.virtualThreadScheduler.parallelism and
> jdk.virtualThreadScheduler.timerQueues makes no difference.
>
> There are no jdk.VirtualThreadPinned or jdk.VirtualThreadSubmitFailed
> events in JFR.
>
>
>
> Additional information:
>
> The application is running in a pod on k8s with 1 CPU allocated to it.
>
> No additional arguments for the JDK.
>
> CPU utilization is less than 15%.
>
> GC happens very infrequently (many minutes apart).
>
>
>
>
>
> [image: VOLVO CAR CORPORATION] <http://volvocars.com/>
>
> Christian
> Fredriksson
>
>
> T +46 734 63 71 06
> *christian.fredriksson.2 at volvocars.com
> <christian.fredriksson.2 at volvocars.com>*
>
> VOLVO CAR CORPORATION
> Connected Car Cloud
> *volvocars.com <http://volvocars.com>*
>
> Registered Office Göteborg, Sweden
> Registration No. 556074-3089
>
>
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/loom-dev/attachments/20251122/8aa97fe4/attachment.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: image001.gif
Type: image/gif
Size: 2421 bytes
Desc: not available
URL: <https://mail.openjdk.org/pipermail/loom-dev/attachments/20251122/8aa97fe4/image001.gif>


More information about the loom-dev mailing list