220. Introducing a scope object (StructuredTaskScope)
So far, we have covered a bunch of problems that use virtual threads directly or indirectly via an ExecutorService
. We already know that virtual threads are cheap to create and block and that an application can run millions of them. We don’t need to reuse them, pool them, or do any fancy stuff. Use and throw is the proper and recommended way to deal with virtual threads. This means that virtual threads are very useful for expressing and writing asynchronous code, which is commonly based on a lot of threads that are capable of blocking/unblocking several times in a short period. On the other hand, we know that OS threads are expensive to create, very expensive to block, and are not easy to put into an asynchronous context.
Before virtual threads (so for many, many years), we had to manage the life cycle of OS threads via an ExecutorService
/Executor
, and we could write asynchronous (or reactive) code via callbacks (you...