Not resuming Virtual Threads?
Ron Pressler
ron.pressler at oracle.com
Fri Jul 3 18:59:35 UTC 2020
Right. Liveness in Java in general is not guaranteed by the language or runtime
but by the thread scheduler. The scheduler for platform threads is the one in the
OS kernel, so the liveness of those threads is whatever liveness that scheduler
guarantees. Java does not guarantee that your finally block *will* be executed;
it just says that *if* your scheduler happens to guarantee the liveness of a thread
then some line of Java code will be executed (actually, it doesn’t even guarantee
that for finally blocks, and there are cases when they are skipped altogether, but
that’s a whole other can of worms). Anyway, same goes for virtual threads, only
we let you provide your own scheduler, written in Java.
Obviously, using a custom thread scheduler or playing with the knobs of a provided
one is advanced usage that carries its own risk, but I don’t see how this is fundamentally
different than an OS that would expose some thread-scheduler knobs which you will
then control using Panama; or even some external program sending signals to your
threads. In other words, unless you know what you’re doing, it’s probably not a good
idea to mess with your threads’ scheduler, whether it’s implemented in a Java library
or in the kernel.
However, if there are any ideas for added safety, I’m certainly open to them.
BTW, continuations will not be exposed (not at first) because you get 99% of their
“business benefit” with 1% of the risks with virtual threads.
— Ron
On 3 July 2020 at 19:25:57, Johannes Kuhn (info at j-kuhn.de) wrote:
Hi Ron,
It's sad to hear that Continuations will not be exposed, at least not at first.
But it does not solve or hide that issue.
Your Argument is only valid if every submitted Runnable to an Executor is eventually called.
If this is not the case, then you have a bug in the Scheduler - at least if I understood you correctly.
The default implementation of the Scheduler is a ForkJoinPool, which comes with a shutdown() method.
I'm probably missing a big chunk of stuff here. It looks for me, that by shutting down the executor, you basically cancel all virtual threads that are currently yielding.
How are their held locks released? (Compare with Thread.terminate())
In the example at [1], the finally block is never executed. You might argument that this is a constructed example, and it is.
Still not sure if I want to debug something like that in production.
- Johannes
[1]: https://gist.github.com/DasBrain/2aebc453894db682d92fe78ae0cf56e2
On 03-Jul-20 18:07, Ron Pressler wrote:
Continuations will not be exposed to programmers directly, at least not at first, so
this is not an issue. When we expose them then, depending on the form that will
take, we can revisit this question.
— Ron
On 3 July 2020 at 16:28:45, Alex Otenko (oleksandr.otenko at gmail.com) wrote:
A similar discussion happened before about try-finally.
Diagnosability of issues with GCed continuations that lose a stack with finally clauses is important. Unlike a stuck thread, we'll get no clue.
Alex
On Fri, 3 Jul 2020, 13:39 Ron Pressler, <ron.pressler at oracle.com> wrote:
Hi.
As Alan explains, a live virtual thread is also always reachable while it is alive.
Unlike platform threads, however, a virtual thread could become unreachable
due to a bug in an implementation of a scheduler, a concurrency constructs or
an IO construct, whether in the core-libraries or in a third-party implementation.
My point was merely that even when such a bug occurs, while certainly
undesirable, no guarantees made by the Java spec are broken (or, at least,
they shouldn’t be). Semantically speaking, the effect of such a bug would be the
same as that of a thread sleeping forever, with an additional ill-effect: observability
tools may not be able to locate the errant virtual thread. This observability
problem could hypothetically be ameliorated by synchronization constructs
recording owning threads, making this situation easier to detect, but given that it
can arise only due to a bug in the first place, then there is no guarantee that the
same buggy construct would record the problem correctly, either.
— Ron
On 3 July 2020 at 03:06:19, David Holmes (david.holmes at oracle.com) wrote:
Hi Ron,
On 3/07/2020 4:05 am, Ron Pressler wrote:
> That could happen if you write your own scheduler or some synchronization
> construct (like a lock). In that case, the virtual thread (and associated
> continuation) will be garbage-collected. From a semantics perspective, it
> is the same as sleeping forever. Java makes no liveness guarantees so this
> does not violate any existing ones.
A Thread sleeping forever does not allow the Thread or its Runnable or
any other reachable object to garbage-collected. Can you please clarify
what the lifecycle of a virtual thread is and how that relates to its
reachability?
For reference a regular Thread is always logically reachable from its
ThreadGroup, until it terminates. And ThreadGroups with active threads
are reachable from their parent ThreadGroups. Hence all live threads are
always reachable.
Thanks,
David
>
> But yeah, this can only happen as a result of a bug in a scheduler or a
> synchronization construct, and certainly inadvisable to do intentionally.
>
> — Ron
>
>
> On 2 July 2020 at 18:45:55, Johannes Kuhn (info at j-kuhn.de) wrote:
>
> After playing around with Virtual Threads a bit, I got to the question:
> What happens if you don't resume a virtual thread?
>
> This could be either done by accident - single thread carrier, that
> waits on an other virtual thread that should be executed on the same
> carrier, but the virtual thread is pinned -
> or on purpose, like not iterating over all elements in my Generator
> example[1]. Or closing the executor once you got an answer.
>
> What happens with those Continuations? Can they be garbage collected?
> What about held locks? How is this different from Thread.suspend?
> Isn't that inherently dangerous?
>
> Just trying to get a better understanding of the model here.
>
> - Johannes
>
> [1]: https://gist.github.com/DasBrain/abfdaa44b44d898f5d3c3888619eb49b
>
More information about the loom-dev
mailing list