Build1 distinct publisher3 min readPublished
JetBrains walks through virtual threads, scoped values and structured concurrency in the IDE, opening on a cancelled future whose work keeps running. Two of the three features are stable in shipped JDKs; the third is on its seventh preview.
The Engineer · Build desk
Compiled by The EngineerSomething wrong?How this is made
Call `cancel(true)` on a `CompletableFuture` and the future flips to cancelled while the task already running in the pool continues to completion, because the interrupt flag is ignored unless the task was wired to a cancellation signal itself [6]. As names for behaviour go, "cancelled" is doing a lot of work there. The object graph looks resolved, the pool thread keeps burning, and nothing in the stack records that the two disagree.
Structured concurrency is what gives a debugger something to draw. JetBrains describes it as treating a group of related threads as a single unit of work, with a parent-child hierarchy that improves observability and makes concurrent code easier to trace and inspect [5]. The hierarchy is the mechanism. A tool can render a tree when the API created edges between parent and child; it cannot render a tree over independent tasks handed to a shared executor, because there is no edge to draw. In the pre-Loom example, `getProfile` passes two suppliers to an executor and waits on `allOf` with a single two-second timeout [8].
So the observability payoff transfers under one condition: your fan-out has to move inside a scope. Rewriting one `getProfile` is cheap. Rewriting every place a service forks work is the bill, and it is paid per call site.
The timing is awkward. Virtual threads have been stable since Java 21 and scoped values since Java 25 [2][3]. Structured concurrency is on its seventh preview in Java 27 [4], six feature releases after virtual threads landed [12]. The two finished features are the ones tooling has least to say about, since a cheap thread is still a thread and a scoped value is an immutable binding that cleans itself up [3]. The feature that produces the tree is the one still labelled preview [4]. Seven rounds is my reason for keeping it on a branch rather than in a hot path.
Error handling carries the same per-call-site cost. `ExecutionException` wraps the real cause, unwrapping is manual, and JetBrains notes the unwrapping chain has to be updated every time a new exception type is introduced [7]. The joint timeout compounds that: `get(2, TimeUnit.SECONDS)` is invoked on `allOf(orderFuture, recFuture)`, so a timeout says the pair was late and not which client was late [13].
One caveat on what I can verify. The text I have sets out the three JEPs and the failure list JetBrains attributes to pre-Loom concurrency, including leaks, cancellation delays and code that is hard to debug [9], and says it will demonstrate the IDE support alongside them [14]. It breaks off inside the `CompletableFuture` example, so I am not going to characterise debugger panels whose description I have not read. The narrower claim I will stand behind: for the two stable features, the JDK stopped being the reason to wait several releases ago, and the version your team now argues about in planning is the IDE's.
Ranked by verification strength, evidence, and original report placement.
JetBrains published a post on blog.jetbrains.com titled "Project Loom in IntelliJ IDEA: Virtual Threads, Scoped Values, and Structured Concurrency", giving an overview of the three features, the problems they solve, how they work together, and how IntelliJ IDEA supports them.
Virtual Threads (JEP 444) have been stable since Java 21; platform threads are expensive and limited in number, while virtual threads are lightweight and managed by the JVM.
Scoped Values (JEP 506) have been stable since Java 25 and provide immutable, automatically cleaned-up data sharing that scales with virtual threads, in place of ThreadLocal variables that are mutable, hard to reason about and prone to memory leaks.
Structured Concurrency (JEP 533) is in its seventh preview in Java 27.
JetBrains states that structured concurrency treats a group of related threads as a single unit of work, making cancellation and error handling predictable and consistent, and provides a clear parent-child thread hierarchy that improves observability and makes concurrent code easier to trace and inspect.
In the pre-Loom example, cancel(true) marks the future as cancelled, but for CompletableFuture the interrupt flag is ignored and the work already running in the pool continues to completion unless it was explicitly wired to a cancellation signal.
Distinct publishers with included, body-backed reporting in this cluster.
1 article · August 27, 2026
Follow any of these and your For You feed starts watching them — no settings page required.
build
JetBrains ships its OpenTelemetry plugin to four more IDEs; instrumentation is still your problem1 distinct publisher
build
JDK 27's nine JEPs are frozen, and two of them change your defaults1 distinct publisher
build
JetBrains asked 15,000 developers how much code agents write. The answers add up to 112 percent1 distinct publisher
build
The only Spring Boot config feature worth arguing about is the one that stops a deploy1 distinct publisher
Evidence-backed comparisons of source perspectives and observed adoption signals. Read the methodology
Which Builder, Operator, and Investor concerns the observed source mix emphasized—not a truth score.
Evidence, demonstrated adoption, hype gap, incentives, and confidence are assessed independently, each on its own current evidence. How these are measured.
Checkable facts, unaccompanied narrator
The hard parts of this story are the easy parts to verify: JEP numbers and the JDK versions they landed in are public record, and the offending code is quoted rather than summarised, so the critique of it can be read straight off the listing. What has no second pair of eyes is the interpretation — that Loom removes the tradeoff, that the rewrite behaves better, that the IDE meaningfully helps. The sample repository is linked, not examined, and no one outside JetBrains appears in our coverage.
Shipped in the JDK, unmeasured in the wild
What can be said about uptake is really about availability. Two of the three features are final API in JDKs already released, so the platform side is settled; the third is preview and has been previewed seven times. Beyond that the story counts nothing — no services running virtual threads, no download or usage figures, no benchmark, no user of the IDE tooling other than the author demonstrating it.
Mostly a question of tense
JetBrains presents three features 'that work together' to eliminate the tradeoff between simplicity and efficiency. Two of them do work today. The third — the one that carries the promises about predictable cancellation, coherent error handling and legible thread hierarchies, which is to say the answers to almost every problem the post enumerates — is on preview number seven, six releases after virtual threads went final. That is not a false claim so much as a future one told in the present tense, and the seventh preview is itself a hint that the API design is not finished.
The IDE vendor is the only narrator
This is IntelliJ IDEA's blog making the case for IntelliJ IDEA. The technical substance survives that — the ignored interrupt flag and the hand-rolled unwrapping chain are real and would be real anywhere — but the selection is not neutral: the pains chosen are pains an IDE can visibly relieve, the arc ends at the Debug tool window, and no competing tooling is mentioned. There is also a platform interest at work, since JetBrains benefits from developers moving to JDK versions its recent releases support best.
Firm on plumbing, thin on consequence
We hold the mechanical claims tightly and the interpretive ones loosely. Version numbers, JEP identifiers and quoted code are things a vendor has no motive to misstate and readers can check, so treat those as settled. What Loom does to real systems, and how much the IDE contributes to getting it right, rests on a single interested tutorial with no measurement attached — assume that half could look different once someone independent tries it.