<div dir="ltr"><div>This question is somewhat tangential to Loom but I thought I'd ask in case the answer is an easy yes or no.<br></div><div><br></div><div>Lately I've been reviewing various attempts at intra-JVM Java "sandboxing", none of which are fully satisfying. I think this is a missed opportunity for Java in general, but that's a separate discussion.<br></div><div><br></div><div>The term "sandbox" has various meanings but for this question think of it simply as what you would need (for example) to build a web site that hosted a live JShell console for educational purposes but all running within a single JVM (there are some examples of this out there like <a href="http://tryjshell.org">tryjshell.org</a> but those use separate processes or Docker). Obviously, execution of arbitrary Java code from random people on the Internet would have to be strictly controlled, and therefore JShell's ExecutionControl would have to run the code in some kind of airtight sandbox.<br></div><div><br></div><div>I just want to focus on one small aspect of doing this: A basic requirement of such a sandbox is the ability to stop a running thread. But currently there's no 100% reliable way to do this in Java, even if you can rewrite the bytecode, because it's impossible to unblock a thread blocked in certain system calls.<br></div><div><br></div><div>What about Thread.stop()? It only works sometimes. Plus it's deprecated (side node, the stated reasons for deprecating this method never made sense to me, because the trade-offs should be left to the programmer to evaluate, and moreover ThreadDeath is no more unsafe than StackOverflowError, which programmers seem to throw all the time :)<br></div><div><br></div><div>FYI here's a simple example showing a thread that can't be stopped no matter what we try:<br></div><div><br><div style="margin-left:40px">public class ThreadNoStop {<br> public static void main(String[] args) throws Exception {<br><br> // Start unstoppable thread<br> final Thread thread = new Thread(() -> {<br> System.out.println("thread: reading stdin...");<br> try {<br> System.in.read();<br> } catch (Throwable t) {<br> System.out.println("thread: caught exception: " + t);<br> }<br> System.out.println("thread: done reading stdin...");<br> });<br> thread.start();<br><br> // Try to kill it any way possible<br> Thread.sleep(500);<br> System.out.println("main: invoking interrupt()...");<br> thread.interrupt();<br> System.out.println("main: invoking stop()...");<br> thread.stop();<br> System.out.println("main: closing System.in...");<br> System.in.close(); // hangs here until there's input<br> System.out.println("main: joining thread...");<br> thread.join();<br> System.out.println("main: done.");<br> }<br>}<br></div></div><div><br></div><div>[JEP 425 Virtual Threads] states:<br></div><div><br></div><div>> The implementations of the networking APIs in <span style="font-family:arial,sans-serif">the <code><a href="http://java.net">java.net</a></code> and <span style="font-family:arial,sans-serif"><code>java.nio.channels</code></span>
pa</span>ckages now work with virtual threads: An operation on a virtual
thread that blocks to, e.g., establish a network connection or read from
a socket, releases the underlying platform thread to do other work.</div><div><br></div><div>This makes it sounds like basically every blocking method is going to have to be adapted so that its state can be "detached" from the platform thread for continuation purposes...? If so, great! </div><div><br></div><div>My question is this: could this work be leveraged to also finally solve the "How do I stop this thread" problem?<br></div><br><div>Even if this new mechanism only worked for virtual threads (or only for platform threads) it would still be a big improvement. <br></div><div><br></div><div>Again, my opinion here but it seems like there really ought to be some official equivalent of Process.destroyForcibly() for Java threads.... it's a basic control/fail-safe.<br></div><div><br><div><div>On a related note - will [JEP 428 Structured Concurrency] guarantee that exiting a StructuredTaskScope never hangs indefinitely?? I guess not.. </div><div><br></div><div>But a better stop mechanism would allow it to make that nice guarantee. This would give it an "automatic cleanup" feature analogous to how try-with-resources automatically hides any extra exceptions thrown by close().</div><div><br></div><div>We could also then add a new method ExecutorService.forceShutdown()...</div><div><br></div><div>This seems like an obvious missing piece to me.<br></div></div><div><br></div><div>Thoughts?</div><div><br></div></div><div>-Archie</div><div><br></div><div>-- <br><div dir="ltr" data-smartmail="gmail_signature">Archie L. Cobbs<br></div></div></div>