8 ms·
Right; Java's virtual threads are (*adjusts glasses*) preemptively-scheduled stackful continuations, meaning (1) that they execute in parallel and in cooperatio
by Twisol 5y ago
Right; Java's virtual threads are (*adjusts glasses*) preemptively-scheduled stackful continuations, meaning (1) that they execute in parallel and in cooperation with the OS' scheduler (*) (which automatically timeslices the CPU amongst threads), and (2) that each continuation is the full call stack at its yield site.
The alternative for point 1 is cooperative scheduling (announcing explicitly when they yield), as you've described.
The alternative for point 2 is "stackless" continuations, where the task yields by returning a callback describing the next step of the task -- or, equivalently, returning some data describing the state of the task, which the task's primary entry point can use to decide where to continue from. (For instance, imagine a function with a big `switch` statement that, when invoked, decides which case to jump into based on its argument, which the caller got from the return value of the last time it got invoked.) Either way, every step of the task constructs and then returns out of its call stack, which can be much more memory efficient, but is also more painful to model tasks in without help from the compiler/language.
(*) Technically, the JVM could take on the role of scheduler as well; it could count the number of bytecode instructions executed, say, and pre-empt a task after some number. This is what Lua supports for some of its sandboxing capabilities. But I think that would be counter to Java's use of an OS thread pool to execute these virtual threads; its own scheduler would be interleaving somewhat unpredictably with the OS'. You'd want to do that if you have long-running jobs that do little I/O (so they hog an OS thread)... but then you'd probably rather put those jobs on actual background worker threads.