Thread::yield in a VirtualThread

Ron Pressler ron.pressler at oracle.com
Tue Jan 3 10:02:52 UTC 2023


Hi.

We’ve changed the implementation of yield in JDK 20 to be more in line with what most people expect it to do (it now looks for other tasks more aggressively) so I suggest you give JDK 20-EA a try. Having said that, yield shouldn’t generally be relied upon to exhibit some specific scheduling behaviour and it doesn’t make more guarantees when called on a virtual thread.

— Ron

> On 26 Dec 2022, at 22:59, KT Nabe <th_nabe at yahoo.com> wrote:
> 
> In writing a simulation for my students, I've encountered some unexpected behavior when virtual threads invoke Thread.yield (understanding that it isn't really clear what guarantees if any are provided).
> 
> In short, if enough* virtual threads are concurrently executing Thread.yield, then no other suspended (sic? yielded/paused) virtual threads will ever be resumed (in my case the other vt's in question were Thread.sleeping, but their deadline has long since expired)
> 
> *enough seems to be =:= the number of CarrierThreads allocated for the default FJP used to run virtual threads (but that's merely an inference from debugging the simulation and may not be what is really going on)
> 
> so I have a check-before-continue (spin) loop:
> 
> A:
> while (0 != (mask & state.get()))
> {
>     Thread.yield();   //nothing to do until some other thread mutates #state
> }
> 
> and other virtual threads:
> B:
> Thread.sleep(1_000L)  //at some point this never returns, and so the next line is never executed
> state.addAndGet(-mask)
> 
> 
> in running the code in a debugger, as best I can tell,
> Thread.yield()
> ....
> Continuation.yield(SCOPE) // returns false?!?
> although the return value is ignored
> I don't know what Continuation::yield returning false actually means, and what its effects are
> 
> What did I expect?
> Well, that yielding a virtual-thread/continuation would result in the opportunity for other virtual threads to be resumed/run; I realize that Thread.yield on a platform thread is more or less undefined, but I assumed that on a virtual thread it would have stronger guarantees (yielding a continuation is kind of the point, isn't it?)
> 
> Now, if I replace A:
> while (0 != (mask & state.get()))
> {
>    // Thread.yield();   //nothing to do until some other thread mutates #state
>    Thread.sleep(10L);
> }
> 
> that solves the problem (there are no program logic errors), and all virtual threads make progress as expected.
> 
> Is this surprising behavior or do I not understand something?
> 
> Thanks.
> -T
> 
> particulars:
> Java: 19.0.1; OpenJDK 64-Bit Server VM 19.0.1+10
> Runtime: OpenJDK Runtime Environment 19.0.1+10



More information about the loom-dev mailing list