SlideShare a Scribd company logo
1 © Marwan Abu-Khalil
© Marwan Abu-Khalil
Page 1
Virtual Threads in Java
Scalability and Performance
in a new Dimension
Marwan Abu-Khalil
2025
1
© Marwan Abu-Khalil
Contact
seminar@abu-khalil.de
Marwan Abu-Khalil
Senior Software Architect
Siemens AG
Berlin, Germany
www.linkedin.com/in/marwan-abu-khalil
Marwan Abu-Khalil
Page 2
Seminars
§ Technische Akademie Esslingen
Software Architecture Introduction
§ iX Workshops, Heise Akademie
Software-Architecture Introduction
Conference Talks
§ W-JAX, Munich November 2025: Virtual Threads Workshop
§ JAX, Mainz Mai 2025: Reactive Streams Workshop
Publication on Virtual Threads
§ Java Spektrum, 2.2025
Virtual Threads in Java: Performance und Skalierbarkeit in neuer Dimension
2
2 © Marwan Abu-Khalil
© Marwan Abu-Khalil
1 Understanding Virtual Threads
2 Performance & Scalability
3 Architecture and Blocking Calls
4 Selecting the suitable Concurrency Approach
5 Emerging Language Features
6 Behind the Scenes
Agenda
Page 4
4
© Marwan Abu-Khalil
1 Understanding Virtual Threads
o Motivation
o What is a thread?
o Mechanics of virtual threads
o Benefits of virtual threads
o API and usage of virtual threads
2 Performance & Scalability
3 Architecture and Blocking Calls
4 Selecting the suitable Concurrency Approach
5 Emerging Language Features
6 Behind the Scenes
Agenda
Page 5
Ask your
questions
in the chat
5
3 © Marwan Abu-Khalil
© Marwan Abu-Khalil
§ Architecture options for concurrent systems
o Reality: (simple + synchronous) OR (complex + asynchronous)
o Wish: simple + asynchronous
§ Typical server application: Blocking calls
o Blocked threads: Expensive resource wasted
§ Idea of virtual threads
o OS thread released during blocking call
Motivation: Scalable Server Applications
Page 6
Thread per request: Many clients => many blocking threads within server
Not Scalable with classic Platform-Threads
6
© Marwan Abu-Khalil
§ Thread in general
o Path of execution (instruction pointer)
o Scheduled and realized by operating system
o Memory for stack and CPU-register set
§ Classic Java Thread is expensive
1. Stack (Memory)
2. OS-Scheduling (CPU)
What is a (classic) Thread?
Page 7
Number of threads
=> coexisting simultaneously
is limited!
7
4 © Marwan Abu-Khalil
© Marwan Abu-Khalil
§ Virtual Thread M:N Platform-Thread (cheap)
o Realized in Java / JVM
o Scheduling in Java / JVM (fast)
o Temporarily executed by a platform thread
o Stack: dynamic
§ Platform-Thread 1:1 OS-Thread (expensive)
o Java Thread: Wrapper around OS-Thread
o Scheduled by OS
o “Carrier” of Virtual Thread
o Stack: static
§ OS thread (expensive)
o Realized by OS
o Scheduled by OS
Layers and Terms:
Virtual-Thread, Platform-Thread (Carrier), OS-Thread
Page 8
8
© Marwan Abu-Khalil
§ Synchronous programming model: Like classic threads
§ Asynchronous execution: When virtual thread blocks, underlying OS thread gets released
§ High scalability: Hundreds of thousands … millions
Idea of Virtual Threads:
Few platform threads run many virtual threads
Page 9
Pool of few expensive platform threads: Executes virtual threads
9
5 © Marwan Abu-Khalil
© Marwan Abu-Khalil
1. Memory: Static Stack vs. Dynamic Stack
§ Platform Thread: "expensive" in terms of memory
o Fixed-size stack
o Assigned at start()
§ Virtual Thread: cheap in terms of memory
o Dynamic Stack of Stack Chunks
o Stack chunks allocated as needed at runtime
o Swap-In / Swap-Out at mounting / unmounting
Virtual Threads: Cheap compared to platform threads
Page 10
Risk: Large dynamic stack => advantage gets lost!
2. CPU: Scheduling in “User Mode”
§ Platform Thread: OS-Scheduling: expensive, slow
§ Virtual Thread: Scheduling in JVM, without OS, fast
Consequence: Non-preemptive scheduling
10
© Marwan Abu-Khalil
§ Programming model identical to classic Java threads
§ Platform thread released as soon as virtual thread blocks
Key Feature:
Automatic release of platform thread in case of blocking
Page 11
// Start
Thread virtualThread = Thread.startVirtualThread(() -> {
System.out.println("Virtual Thread id: " + Thread.currentThread().threadId());
});
// Wait
virtualThread.join();
11
6 © Marwan Abu-Khalil
© Marwan Abu-Khalil
Blocking – Releasing: Step by Step
Page 13
3
2
1
4 5
13
© Marwan Abu-Khalil
Synchronous vs. asynchronous programming
Page 14
Flux.range(1, 8)
// DB Access: 1 Sec blocking
.map( and -> readFromDatabase(i))
// Stage decoupling
.publishOn(Schedulers.parallel())
.map( list -> computeCPUData(list))
.publishOn(Schedulers.parallel())
.subscribe( list->showInUI(cpuList));
Asynchronous Execution: Reactive Streams
for(int i = 1 ; i <= 8; ++i) {
final int inputValue = i;
Thread thread = new Thread(() ->{
// DB Access: 1 Sec blocking
var databaseList = readFromDatabase(inputValue);
// CPU: 1 Sec computing
var cpuList = computeCPUData(databaseList);
// UI
showInUI(cpuList);
});
thread.start();
}
Synchronous: Thread per Request
for(int i = 1 ; i <= 8; ++i) {
final int arg = i;
// Stage 1: DB Access
CompletableFuture.supplyAsync(()->readFromDatabase(arg))
// Callback Stage 2: CPU Computation
.thenApplyAsync((List<Integer> dbResultSet) -> {
return computeCPUData(dbResultSet);
})
// Callback Stage 3: UI Rendering
.thenAcceptAsync((cpuData) ->{
showInUI(cpuData);
});
}
Asynchronous Programming: CompletableFutures
Simple but inefficient
Efficient, but own programming model
Complex
Programming
14
7 © Marwan Abu-Khalil
© Marwan Abu-Khalil
Goal
§ Simple sequential programming
o Like classic threads
§ Efficient asynchronous execution
o Wie Reactive Streams
Mechanism
o OS thread: Release in case of blocking
o Asynchrony: Managed automatically
Technological background
o Mapping Virtual -> Platform-Thread
o Operating System asynchronous IO
o Non-preemtive scheduling
Virtual Threads combine the best of both worlds:
Sequential programming + asynchronous execution
Page 15
15
© Marwan Abu-Khalil
§ 1. Why is a platform thread expensive?
o Stack: Memory
o OS-Scheduling: CPU
§ 2. Why is a virtual thread cheap?
o Dynamic stack
o JVM scheduling
o Executed by platform thread
§ 3. What happens when a virtual thread calls a blocking OS operation?
o Carrier thread released
o Carrier executes other virtual thread
o After blocking call returns:
Virtual thread runnable
Recap (print version)
Page 22
22
8 © Marwan Abu-Khalil
© Marwan Abu-Khalil
What happens when a new virtual thread is created?
§ Instance of virtual thread is created
§ New virtual thread mapped to platform thread from pool
§ Associated platform thread runs virtual thread
§ Platform thread called "carrier thread"
API and usage of virtual threads
Page 26
26
© Marwan Abu-Khalil
1. Class Thread
2. ExecutorService (Pool)
3. ThreadBuilder
Virtual-Thread extends Thread
=> Key for simple migration
Ways to start a Virtual Thread
Page 27
Start: Class Thread
Thread virtualThread = Thread.startVirtualThread(() ->{});
Start: ExecutorService
Executors.newVirtualThreadPerTaskExecutor().submit(() -> {});
Start: ThreadBuilder
Thread.ofVirtual().name("MyVirtualThread").unstarted(() -> {}).start();
27
9 © Marwan Abu-Khalil
© Marwan Abu-Khalil
§ ExecutorService creation: newVirtualThreadPerTaskExecutor()
§ Virtual threads never reused
§ Virtual thread performs one single task, then dies!
§ Future: Obtain result asynchronously
Option 2: Executor Service
Page 29
// Pool Interface: ExecutorService
ExecutorService executor =
Executors.newVirtualThreadPerTaskExecutor();
// Start
Future<?> threadResult = executor.submit(() -> {
System.out.println("Virtual Thread via Executor ”
+ Thread.currentThread());
});
// Wait
threadResult.get();
29
© Marwan Abu-Khalil
§ Virtual threads can be instantiated at ”unlimited” amount
o Since they are extremely "cheap"
§ Reuse is pointless
o Virtual threads should never be pooled, they are too cheap
o Only platform threads should be pooled (e.g. by ExecutorService)
§ Beware of "deep stacks"
o Performance advantage may be lost
o Long running tasks are not good candidates for virtual threads
Important Guidlines for using Virtual Threads
Page 33
33
10 © Marwan Abu-Khalil
© Marwan Abu-Khalil
1 Understanding Virtual Threads
2 Performance & Scalability
o Is a Virtual Thread faster?
o How can more Concurrency increase Performance?
o Examples for Scalability and Performance
3 Architecture and Blocking Calls
4 Selecting the suitable Concurrency Approach
5 Emerging Language Features
6 Behind the Scenes
Agenda
Page 34
Ask your
questions
in the chat
34
© Marwan Abu-Khalil
NO! Computing speed on CPU is identical!!!
§ How can virtual threads increase performance?
§ Virtual threads "only" increase number of simultaneously
blocking calls
=> More simultaneous tasks
=> More clients at the same time
=> Higher scalability
=> Higher throughput
=> Overall performance improves
Is a Virtual Thread faster than a Platform Thread???
Page 35
35
11 © Marwan Abu-Khalil
© Marwan Abu-Khalil
§ Little’s law (John Little, 1954)
o Theoretic background for performance increase
o Increased concurrency with constant response time implies higher throughput
§ Modern OS
o Can handle many (thousands) simultaneous threads
o BUT: Application shoud use few, because they are expensive
§ Thread Pools provide efficency
o Pool size according to number of CPU-cores
o Threads kept busy
Why is scalabilty a challenge with classic threads?
…and how can we gain performance?
Page 36
Little’s Law
Concurrency => Throughput => Performance!
36
© Marwan Abu-Khalil
More simultaneous Clients
through Thread Virtualization
Page 37
Classic Thread Model
Expensive platform threads block during I/O
=> Few concurrent clients
Virtual Thread Model
Platform threads always running
=> Many concurrent clients
37
12 © Marwan Abu-Khalil
© Marwan Abu-Khalil
§ 10,000 Platform-Threads start
o After 4000 threads crash: OutOfMemoryError
§ Alternative: Start 10,000 virtual threads
o Runs smoothly
§ Crucial: blocking OS call (e.g.sleep())
§ Effect of Virtual Threads Architecture
o Number of parallel tasks massively increased
o Little's Law: Throughput increased
Example Scalability
Page 39
Platform Threads: Crash
Virtual Threads: Scale
Real limit depends
on OS, HW and
configuration
39
© Marwan Abu-Khalil
§ Platform threads start
§ sleep(): Blocking call
§ After 4000 threads are started: OutOfMemoryError
10,000 Platform Threads: Crash
Page 40
for(int i = 0; i < 1_000_0; ++i) {
final int cnt = i;
// Launch Platform Thread
Thread thread = new Thread(()->{
System.out.println("New OS Thread"+ cnt);
// Sleep (blocking call)
Thread.sleep(1000);
// Exception handling omitted
});
thread.start();
}
2
1
Adapt thread count and
sleep time to your
platform for experiments
3
40
13 © Marwan Abu-Khalil
© Marwan Abu-Khalil
10,000 Virtual-Threads: Start easily
Page 41
for(int i = 0; i < 10_000; ++i) {
final int cnt = i;
// Starting virtual thread
Thread.startVirtualThread(()->{
System.out.println(”New virtual Thread: " + cnt);
sleep(1000);
});
}
Where does this help?
Scalable Server
41
© Marwan Abu-Khalil
Performance Example:
Increase through virtual threads factor 10!!
Page 43
// Variant 1 Platform Threads: 10 seconds, Pool of 1000 Threads
//ExecutorService pool = Executors.newFixedThreadPool(1000);
// Variant 2 Virtual Threads: 1 second
ExecutorService pool = Executors.newVirtualThreadPerTaskExecutor();
long start = System.currentTimeMillis();
for(int i = 0 ; i <= 10_000; ++i) {
final int loop_cnt = i;
pool.submit(() -> {
// Blocking call (exception handling omitted)
Thread.sleep(1000);
System.out.println("Job " + loop_cnt + " woke up " +
(System.currentTimeMillis() - start) / 1000 + " Seconds ");
}
}
One second with 10,000 virtual threads
10 seconds with 1,000 platform threads
More simultaneous tasks
=>
Better overall performance
43
14 © Marwan Abu-Khalil
© Marwan Abu-Khalil
Positive
§ Higher scalability compared to platform
threads
§ Performance can be massively improved by
high scalability (Little's Law)
Conclusion on
Performance and Scalability of Virtual Threads
Page 51
Negative
§ Blocking calls necessary to profit form virtual
threads
§ Not all architectures, use cases, and systems
can benefit from virtual thread migration
51
© Marwan Abu-Khalil
1 Understanding Virtual Threads
2 Performance & Scalability
3 Architecture and Blocking Calls
o Rules for Migration
o Relevance of blocking Calls
o Examples for Scheduling Behavior
4 Selecting the suitable Concurrency Approach
5 Emerging Language Features
6 Behind the Scenes
Agenda
Page 52
Ask your
questions
in the chat
52
15 © Marwan Abu-Khalil
© Marwan Abu-Khalil
1. Performance limited by amout of available threads
o Application could run faster with more threads
o Rationale: Virtual threads only add concurrency, not paralleleism, not computing power
2. Significant time spent in blocking OS-calls („IO-Bound“)
o Rationale: Virtual threads change system behaviour only during blocking OS-calls
Two necessary Pre-Conditions for Performance Gain
through Migration to Virtual Threads
Page 53
CPU-bound Apps
DO NOT BENEFIT!!!
except in rare corner cases where
context switching is a bottleneck
see Quarkus Docu:
https://quarkus.io/guides/virtual-threads#cpu-bound
53
© Marwan Abu-Khalil
§ Typical server application
o Significant amount of time: Blocking calls
o E.g. database, internal and external services
§ Thread per Request
o Simple to program
o Scales only to thread limit of OS
§ Idea of Virtual Threads
o Release OS thread on blocking call
o Inside the JVM process: Lock.lock(), Thread.sleep()...
o Outside, I/O: Socket, File Access...
Relevance and handling of blocking calls (recap)
Page 54
54
16 © Marwan Abu-Khalil
© Marwan Abu-Khalil
§ A lot of virtual threads wish to execute sleep()
§ Single Platform Thread: Executes all virtual threads one at a time
§ All virtual threads block in sleep(): transferred to unmouted state
§ sleep() call returns: virtual thread is runnable again
Example:
Many virtual threads call sleep() at the same time
Page 57
57
© Marwan Abu-Khalil
§ Many (1000) Virtual Threads
o Start
o Each calls sleep()
§ Few (8) Platform Threads
o Execute 1000 Virtual Threads
Output shows: Many virtual threads executed by a few
platform threads
Page 58
for(int i = 0; i < 1000; ++i) {
final int cnt = i;
Thread.startVirtualThread(() ->{
System.out.println("Virtual Thread Nr. " + cnt
+ " " + Thread.currentThread());
// Blocking call releases Carrier-Thread
sleep(1000);
});
}
1000 Virtual Threads
8 Platform
Threads
58
17 © Marwan Abu-Khalil
© Marwan Abu-Khalil
Scheduler Dynamics: Many Virtual Threads call sleep()
60
© Marwan Abu-Khalil
Scenario: Queue of limited size
§ Many Virtual Threads call take(): blocking
§ Few Virtual Threads call put(): blocking
§ Executed by limited size Platform Thread Pool
Example: Producer-Consumer with Blocking Queue
Page 66
Comparison: Fork-Join-Tasks
§ May deadlock in queuing scenario
§ Do not handle blocking efficiently
Behavior
§ Carrier released on blocking take() and put()
§ All threads run smoothly, no blocking
66
18 © Marwan Abu-Khalil
© Marwan Abu-Khalil
§ 10 virtual threads on 8-core computer, array with 10 slots
§ Each thread counts up counter in array infinitely
§ Result: only the first 8 slots are accessed, as only 8 virtual threads run actually
§ Platform threads instead: All fields in array are incremented
Example:
Missing preemption changes program semantics
Page 69
long[] numbers = new long[10];
// 10 Virtual Threads:
// Only 8 array slots processed on 8-Core CPU
ExecutorService pool =
Executors.newVirtualThreadPerTaskExecutor();
for(int i = 0 ; i < 10; ++i) {
final int j = i;
pool.execute(() ->{
while(true) {
numbers[j]+=1;
}
});
}
sleep(1000);
System.out.println(Arrays.toString(numbers));
Rare corner
case….
69
© Marwan Abu-Khalil
Virtual threads characteristics
§ Reuse is pointless
o Virtual threads never pooled!
o Only platform threads pooled (ExecutorService)
§ Beware of "deep stacks”
o Performance advantage may vanish
§ No Preemption
o Application semantics can change
Rules for the use of Virtual Threads and for Migration
Recap / Summary
Page 71
Migration requires two Pre-Conditions
1. Performance limited by amount of available threads
2. Significant time spent in blocking OS-calls
71
19 © Marwan Abu-Khalil
© Marwan Abu-Khalil
1 Understanding Virtual Threads
2 Performance & Scalability
3 Architecture and Blocking Calls
4 Selecting the suitable Concurrency Approach
o Reactive Streams comparison
o JDK Alternatives: Fork-Join, Parallel Streams
5 Emerging Language Features
6 Behind the Scenes
Agenda
Page 91
Ask your
questions
in the chat
91
© Marwan Abu-Khalil
Discussions between Reactive Streams and Virtual Threads Advocates
§ Arguments of virtual thread community (e.g. Brian Getz)
o Reactive streams don't fit well into Java Platform
o Unit of application's concurrency is pipeline stage
o Unit of the platform's concurrency is thread
o Tools, stack traces, profilers, debuggers not well usable
o "Foreign" programming model:
without support in Java language / platform
See https://www.infoq.com/articles/java-virtual-threads/ „What About Reactive“
§ Argument of ReacitveStreams community (e.g. Thomasz Nurkiewitz)
o Only benefit of virtual threads programming model: easy asynchrony
o Other Reactive Streams features missing: Backpressure, Change Propagation, Composability
See: https://www.infoq.com/presentations/loom-java-concurrency/
Reactive Streams Comparison
Page 93
Flux.range(1, 8)
// DB Access: 1 Sec blocking
.map( and -> readFromDatabase(i))
// Stage decoupling
.publishOn(Schedulers.parallel())
.map( list -> computeCPUData(list))
.publishOn(Schedulers.parallel())
.subscribe( list->showInUI(cpuList));
Reactive Streams Example
93
20 © Marwan Abu-Khalil
© Marwan Abu-Khalil
Virtual Threads
§ Make IO-bound applications scalable
See: Brian Getz,
Virtual Threads: new Foundations for Java High Scale Applications
https://www.infoq.com/articles/java-virtual-threads/
ForkJoin and ParallelStreams
§ Ideal for CPU-bound applications
o Many asynchronous tasks run on top of few threads
§ Not suitable for IO bound applications
o Blocking OS call not handled well
o Blocks underlying pool thread
o Risk: Deadlock, or alternatively high memory consumption if pool grows
Comparison Virtual-Threads vs.
Fork-Join-Tasks & Parallel-Streams
Page 94
IO-bound optimized
CPU-bound optimized
Fork Join Tasks
Tech-Stack
!"#A%C"'(
F*+A%F#,,
FJ#,*.%/""0
1/O
1/O
P4%45J,.S0,#
/*#*00,0T4U#,*9+
!"#$B&'(F*+',
-./&(.$0*'"-1O#.-"+-,
1"(U*'(,#+T:T;##*<+
/"F"3+&-(.
4=0'U,#*U"#
#"-F*F*+'34/"F"
Virtual-Thread
Blocking Call
94
© Marwan Abu-Khalil
§ 2 Virtual Threads run and call put()
§ Queue full, put() blocks V-T 2
§ Carrier thread P-T 2 is freed
§ P-T 2 now executes V-T 3
§ take() frees space in the queue
§ V-T 2 unblocking
§ but has no carrier yet
Blocking Queue with Virtual Threads
Scenario
Page 95
95
21 © Marwan Abu-Khalil
© Marwan Abu-Khalil
§ Fork-Join-Tasks
o Blocking-Queue: Deadlock
§ put() blocks when queue full
§ ForkJoinTasks block Pool-Threads
§ No more pool threads
§ No ForkJoinTask runs for take()
What fork-join tasks can't do that virtual threads can:
e.g. producer-consumer with blocking queue
Page 96
96
© Marwan Abu-Khalil
Technology selection
according to functional and non fuctional properties
Page 103
Usecase
Virtual Thread Platform
Thread
Fork-Join-Task Parallel-
Stream
Reactive-
Stream
Blocking-IO Yes
perfect use-case
Yes No
Blocks Pool
Thread
No
Blocks Pool
Thread
Yes
Asynchrony
System
Architecture
Structure
Yes
But focus on
server scalabilty
Yes
Perfect use case
No
No blocking IO
handling
No
More design
level, no blocking
IO
Yes
Many subscribers
back-pressure
Recursive
Algorithm
Yes
Cheap parallelsim
Risk: No
preemption
Probably not
Caution: Memory
requirements
Yes
Perfect Use-Case
No
Recursion not
feasible within
pipeline
Probably not
Focus: distributed
concurrent
system
Pipeline Data
Processing
Probably not
No API support
Probably not
No API support
No
No blocking
Yes
Perfect use-case
Yes
not primarily for
parallelizing
pipeline
Lots of data
infinite
streams
No
Short
running
Yes
Long running
No
short running
No
Cannot be
partitioned
efficiently
Yes
Perfect use-case
API
103
22 © Marwan Abu-Khalil
© Marwan Abu-Khalil
1 Understanding Virtual Threads
2 Performance & Scalability
3 Architecture and Blocking Calls
4 Selecting the suitable Concurrency Approach
5 Emerging Language Features
o Structured Concurrency
o Scoped Values
6 Behind the Scenes
Agenda
Page 104
Ask your
questions
in the chat
104
© Marwan Abu-Khalil
§ Goals
o Handle group of virtual threads as single unit
o Eliminate concurrent programming risks regarding cancellation and shutdown
§ Central idea
o Combine parallel tasks into a "scope" that succeed or fail together
o One thread throws exception: Full “scope” exited
§ Constructs
o StructuredTaskScope: Combines multiple virtual threads into one unit
o Subtask<String> subTask1 = scope.fork(() -> {...}): fork starts new Virtual Thread
o scope.join(): Waits for all threads in the scope
o scope.throwIfFailed(); Terminates scope by an exception when a thread throws errors
o StructuredTaskScoped.Joiner: Configures join()-behavioir, e.g.
anySuccessfulResultOrThrow() / awaitAll() / awaitAllSuccessfulOrThrow(),
https://openjdk.org/jeps/505 (for Java 25)
https://openjdk.org/jeps/480 (for Java 23)
Structured Concrurency
JEP 480, 505, Preview
Page 105
Java 25 / Java 23 differences, e.g:
public static <T> StructuredTaskScope<T, Void> open()
105
23 © Marwan Abu-Khalil
© Marwan Abu-Khalil
Structured Concurrency Example (Java 23 Version)
Page 106
try(var scope = new StructuredTaskScope.ShutdownOnFailure()){
// Start Subtask
Subtask<String> subTask1 = scope.fork(() -> {
System.out.println("Task 1 called in " + Thread.currentThread());
return "Hello";
});
// Start Subtask
Subtask<String> subTask2 = scope.fork(() -> {
for(int i = 0; i < 1000; ++i) {
System.out.println("Task 2 loop: " + i +" called in " + Thread.currentThread());
}
return ”World";
});
scope.join();
scope.throwIfFailed();
System.out.println(subTask1.get());
System.out.println(subTask2.get());
}
Two threads handled as
one singe unit
wait for all!
propagate failures
common “scope” bundles
virtual threads together
106
© Marwan Abu-Khalil
§ Idea
o ThreadLocal variables optimized for use with virtual threads
o Immutable
o Cheap
o Shared by a hierarchy of virtual threads in a scope (StructuredTaskScope)
§ Elements
o Declaration
static final ScopedValue<... > V = ScopedValue.newInstance();
o Setting the value
ScopedValue.where(V, <value>)
o Binding to lambda expression
ScopedValue.run(() -> { ... V.get() ... call methods ... });
o Accessing the value
V.get()
https://openjdk.org/jeps/487
Scoped Values
JEP 487, Preview
Page 108
108
24 © Marwan Abu-Khalil
© Marwan Abu-Khalil
Scoped Values Example
Page 109
Declaring Scoped Value
static ScopedValue<String> SCOPED_VALUE_EXAMPLE =
ScopedValue.newInstance();
Thread virtThread1 = Thread.startVirtualThread(() -> {
Bind scoped value with where()
and define scope with run()
ScopedValue.where(SCOPED_VALUE_EXAMPLE, "Hallo").run(() -> {
String valueinThread = SCOPED_VALUE_EXAMPLE.get();
System.out.println("Thread 1: " + valueinThread);
});
});
Thread virtThread2 = Thread.startVirtualThread(() -> {
Different value in another scope
ScopedValue.where(SCOPED_VALUE_EXAMPLE, "GutenTag").run(() -> {
String valueinThread = SCOPED_VALUE_EXAMPLE.get();
System.out.println("Thread 2: " + valueinThread);
});
});
single instance
Assign value for thread 1
other value for thread 2
different
outputs
Core feature: Anywhere in the
code available without argument
109
© Marwan Abu-Khalil
1 Understanding Virtual Threads
2 Performance & Scalability
3 Architecture and Blocking Calls
4 Selecting the suitable Concurrency Approach
5 Emerging Language Features
6 Behind the Scenes
o JVM Virtual Threads Architecture
o Consequences for Application Design
Agenda
Page 110
Ask your
questions
in the chat
110
25 © Marwan Abu-Khalil
© Marwan Abu-Khalil
1. Blocking call: Carrier Thread released
§ M:N Mapping: Virtual thread run by several platform threads
§ New carrier after blocking call
2. Dynamic Stack
§ Stack can grow and shrink (StackChunk objects, lazy-loading)
§ Mounting / unmounting:
Stack-frames copied from carrier's stack to heap (& vice versa)
3. Continuations
§ Virtual threads are realized as “continuations”
§ “one shot delimited continuations” theoretic concept behind
4. User Mode Scheduling
§ No preemption: A virtual thread runs to completion
Architecture of virtual threads = > Consequences for App Design and Behavior
Page 111
Changed program
semantics, e.g. starvation
Cheap scheduling
Beware of deep stacks
Memory saving
Only IO-bound apps benefit
Performance optimization
Easy migration
Automatic asynchrony
111
© Marwan Abu-Khalil
Conclusion on Virtual Threads
Page 114
Positive
§ Extremely highly scalable
o Many thousands of simultaneous tasks
§ Massive performance boost possible
o Throughput
o Little’s Law
§ Saved resources
o Memory and CPU
o Platform Threads
§ Simple programming model
o Like classic threads
o Easy migration
o Sequential programming, asych. execution
Carefully consider before migration
§ Only effective with significant blocking time
o Blocking time per client call relevant
o Only for IO bound applications
o No benefit for computationally intensive
applications
§ High degree of concurrency required
o Unreachable with platform threads
o Thousands, possibly millions
§ Semantic change possible (rare case!)
o No preemption
114
26 © Marwan Abu-Khalil
© Marwan Abu-Khalil
1 Understanding Virtual Threads
2 Performance & Scalability
3 Architecture and Blocking Calls
4 Selecting the suitable Concurrency Approach
5 Emerging Language Features
6 Behind the Scenes
Agenda in Retrospect
Page 115
115
© Marwan Abu-Khalil
- Oracle Java Core Libraries Documentation: https://docs.oracle.com/en/java/javase/21/core/virtual-threads.html
- JEP Virtual Threads https://openjdk.org/jeps/425 and https://openjdk.org/jeps/444
- JEP Structured Concurrency: https://openjdk.org/jeps/453, https://openjdk.org/jeps/505
- Brian Getz, 2022: New Foundations for Java High Scale Applications https://www.infoq.com/articles/java-virtual-
threads/
- Michael Inden, 2025: Java 21 LTS bis 24 -- Coole neue Java-Features: Modernes Java leicht
gemacht https://amzn.eu/d/2FrSinA
- Sven Woltmann, 2022, nice little examples: https://www.happycoders.eu/de/java/virtual-threads/
- Nicolai Parlog, Oracle, 2022: https://blogs.oracle.com/javamagazine/post/java-loom-virtual-threads-platform-threads
- Lutz Hühnken, entwickler.de 2020 https://entwickler.de/java/blick-in-die-fernere-zukunft
- Reinald Menge-Sonntag, heise online 2022: https://www.heise.de/news/Java-19-verbessert-die-Nebenlaeufigkeit-mit-virtuellen-
Threads-aus-Project-Loom-7269453.html
- Ron Presler, QCon 2019: https://www.infoq.com/presentations/continuations-java/
- Thomasz Nurkiewitz, QCon 2022: https://www.infoq.com/presentations/loom-java-concurrency/
- Ricardo Cardin, 2023, good Examples about Threadpool and Scheduling: https://blog.rockthejvm.com/ultimate-
guide-to-java-virtual-threads/#3-how-to-create-a-virtual-thread
- Marwan Abu-Khalil, 2025 , Virtual Threads in Java: Performance und Skalierbarkeit in neuer
Dimension, https://www.sigs.de/artikel/virtual-threads-in-java-performance-und-skalierbarkeit-in-neuer-dimension/
Literature and web links
(some are in German, but still great!)
Page 116
116
27 © Marwan Abu-Khalil
© Marwan Abu-Khalil
Contact
seminar@abu-khalil.de
Marwan Abu-Khalil
Senior Software Architect
Siemens AG
Berlin, Germany
www.linkedin.com/in/marwan-abu-khalil
Marwan Abu-Khalil
Page 117
Seminars
§ Technische Akademie Esslingen
Software Architecture Introduction
§ iX Workshops, Heise Akademie
Software-Architecture Introduction
Conference Talks
§ W-JAX, Munich November 2025: Virtual Threads Workshop
§ JAX, Mainz Mai 2025: Reactive Streams Workshop
Publication on Virtual Threads
§ Java Spektrum, 2.2025
Virtual Threads in Java: Performance und Skalierbarkeit in neuer Dimension
117
© Marwan Abu-Khalil
Page 118
Q&A
Ask your
QUESTIONS
in the chat!
118

More Related Content

PDF
Virtual Threads in Java: A New Dimension of Scalability and Performance
Tier1 app
 
PDF
A first look into the Project Loom in Java
Lukas Steinbrecher
 
PPT
Java Multithreading
Rajkattamuri
 
PPT
Java multithreading
Mohammed625
 
PDF
Loom Virtual Threads in the JDK 19
José Paumard
 
PDF
Here comes the Loom - Ya!vaConf.pdf
Krystian Zybała
 
PPT
Java
mdfkhan625
 
PPT
Multithreading
F K
 
Virtual Threads in Java: A New Dimension of Scalability and Performance
Tier1 app
 
A first look into the Project Loom in Java
Lukas Steinbrecher
 
Java Multithreading
Rajkattamuri
 
Java multithreading
Mohammed625
 
Loom Virtual Threads in the JDK 19
José Paumard
 
Here comes the Loom - Ya!vaConf.pdf
Krystian Zybała
 
Multithreading
F K
 

Similar to Troubleshooting Virtual Threads in Java! (20)

PDF
Looming Marvelous - Virtual Threads in Java Javaland.pdf
jexp
 
PPTX
Lecture 23-24.pptx
talha ijaz
 
PPT
multithreading
Rajkattamuri
 
PPT
Java
Khasim Cise
 
PDF
Multithreading Introduction and Lifecyle of thread
Kartik Dube
 
PPT
Threads
Abhishek Khune
 
PPT
Java multi threading
Raja Sekhar
 
PPTX
Multithreading.pptx
PragatiSutar4
 
PPTX
Multi threading
gndu
 
PPTX
Loom promises: be there!
Jean-Francois James
 
PPTX
Threading.pptx
BalasundaramSr
 
PDF
Loom me up Scotty! Project Loom - What's in it for Me?
Haim Yadid
 
PPTX
Multi Threading
Ferdin Joe John Joseph PhD
 
PPTX
Multi-Threading in Java power point presenetation
AshokRachapalli1
 
PPT
JAVA MULTITHREDED PROGRAMMING - LECTURES
rm170484
 
PPT
Advanced Java Programming for Beginners.
rm170484
 
PPTX
MSBTE Computer Engineering JPR java. multi. threading.pptx
kunalgaikwad1705
 
PPT
multithreading, creating a thread and life cycle in java.ppt
shikhaverma566116
 
PPTX
Java Thread & Multithreading
jehan1987
 
Looming Marvelous - Virtual Threads in Java Javaland.pdf
jexp
 
Lecture 23-24.pptx
talha ijaz
 
multithreading
Rajkattamuri
 
Multithreading Introduction and Lifecyle of thread
Kartik Dube
 
Java multi threading
Raja Sekhar
 
Multithreading.pptx
PragatiSutar4
 
Multi threading
gndu
 
Loom promises: be there!
Jean-Francois James
 
Threading.pptx
BalasundaramSr
 
Loom me up Scotty! Project Loom - What's in it for Me?
Haim Yadid
 
Multi-Threading in Java power point presenetation
AshokRachapalli1
 
JAVA MULTITHREDED PROGRAMMING - LECTURES
rm170484
 
Advanced Java Programming for Beginners.
rm170484
 
MSBTE Computer Engineering JPR java. multi. threading.pptx
kunalgaikwad1705
 
multithreading, creating a thread and life cycle in java.ppt
shikhaverma566116
 
Java Thread & Multithreading
jehan1987
 
Ad

More from Tier1 app (20)

PPTX
Java Native Memory Leaks: The Hidden Villain Behind JVM Performance Issues
Tier1 app
 
PPTX
Key Challenges in Troubleshooting Customer On-Premise Applications
Tier1 app
 
PPTX
Micro-Metrics Every Performance Engineer Should Validate Before Sign-Off
Tier1 app
 
PPTX
GC Tuning: A Masterpiece in Performance Engineering
Tier1 app
 
PPTX
Troubleshooting JVM Outages – 3 Fortune 500 Case Studies
Tier1 app
 
PPTX
Troubleshooting JVM Outages – 3 Fortune 500 case studies
Tier1 app
 
PPTX
How to Troubleshoot 9 Types of OutOfMemoryError
Tier1 app
 
PPTX
Not So Common Memory Leaks in Java Webinar
Tier1 app
 
PPTX
Common Memory Leaks in Java and How to Fix Them
Tier1 app
 
PPTX
7 Micro-Metrics That Predict Production Outages in Performance Labs Webinar
Tier1 app
 
PPTX
Top 5 Java Performance Problems Presentation!
Tier1 app
 
PPTX
Mastering Thread Dump Analysis: 9 Tips & Tricks
Tier1 app
 
PPTX
How to Check and Optimize Memory Size for Better Application Performance
Tier1 app
 
PPTX
TroubleshootingJVMOutages-3CaseStudies (1).pptx
Tier1 app
 
PPTX
TroubleshootingJVMOutages-3CaseStudies.pptx
Tier1 app
 
PPTX
Major Outages in Major Enterprises Payara Conference
Tier1 app
 
PPTX
DECODING JAVA THREAD DUMPS: MASTER THE ART OF ANALYSIS
Tier1 app
 
PPTX
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
Tier1 app
 
PPTX
Top-5-java-perf-problems-jax_mainz_2024.pptx
Tier1 app
 
PPTX
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
Tier1 app
 
Java Native Memory Leaks: The Hidden Villain Behind JVM Performance Issues
Tier1 app
 
Key Challenges in Troubleshooting Customer On-Premise Applications
Tier1 app
 
Micro-Metrics Every Performance Engineer Should Validate Before Sign-Off
Tier1 app
 
GC Tuning: A Masterpiece in Performance Engineering
Tier1 app
 
Troubleshooting JVM Outages – 3 Fortune 500 Case Studies
Tier1 app
 
Troubleshooting JVM Outages – 3 Fortune 500 case studies
Tier1 app
 
How to Troubleshoot 9 Types of OutOfMemoryError
Tier1 app
 
Not So Common Memory Leaks in Java Webinar
Tier1 app
 
Common Memory Leaks in Java and How to Fix Them
Tier1 app
 
7 Micro-Metrics That Predict Production Outages in Performance Labs Webinar
Tier1 app
 
Top 5 Java Performance Problems Presentation!
Tier1 app
 
Mastering Thread Dump Analysis: 9 Tips & Tricks
Tier1 app
 
How to Check and Optimize Memory Size for Better Application Performance
Tier1 app
 
TroubleshootingJVMOutages-3CaseStudies (1).pptx
Tier1 app
 
TroubleshootingJVMOutages-3CaseStudies.pptx
Tier1 app
 
Major Outages in Major Enterprises Payara Conference
Tier1 app
 
DECODING JAVA THREAD DUMPS: MASTER THE ART OF ANALYSIS
Tier1 app
 
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
Tier1 app
 
Top-5-java-perf-problems-jax_mainz_2024.pptx
Tier1 app
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
Tier1 app
 
Ad

Recently uploaded (20)

PDF
Using licensed Data Loss Prevention (DLP) as a strategic proactive data secur...
Q-Advise
 
PPT
Activate_Methodology_Summary presentatio
annapureddyn
 
PDF
Salesforce Implementation Services Provider.pdf
VALiNTRY360
 
PPTX
Presentation about variables and constant.pptx
safalsingh810
 
PPTX
ASSIGNMENT_1[1][1][1][1][1] (1) variables.pptx
kr2589474
 
PDF
advancepresentationskillshdhdhhdhdhdhhfhf
jasmenrojas249
 
PPT
Why Reliable Server Maintenance Service in New York is Crucial for Your Business
Sam Vohra
 
PDF
lesson-2-rules-of-netiquette.pdf.bshhsjdj
jasmenrojas249
 
PDF
New Download MiniTool Partition Wizard Crack Latest Version 2025
imang66g
 
PDF
Summary Of Odoo 18.1 to 18.4 : The Way For Odoo 19
CandidRoot Solutions Private Limited
 
PPTX
The-Dawn-of-AI-Reshaping-Our-World.pptxx
parthbhanushali307
 
PPTX
Visualising Data with Scatterplots in IBM SPSS Statistics.pptx
Version 1 Analytics
 
PPTX
AI-Ready Handoff: Auto-Summaries & Draft Emails from MQL to Slack in One Flow
bbedford2
 
PDF
49784907924775488180_LRN2959_Data_Pump_23ai.pdf
Abilash868456
 
PPTX
Odoo Integration Services by Candidroot Solutions
CandidRoot Solutions Private Limited
 
PPTX
GALILEO CRS SYSTEM | GALILEO TRAVEL SOFTWARE
philipnathen82
 
PPTX
Contractor Management Platform and Software Solution for Compliance
SHEQ Network Limited
 
PDF
New Download FL Studio Crack Full Version [Latest 2025]
imang66g
 
PDF
ChatPharo: an Open Architecture for Understanding How to Talk Live to LLMs
ESUG
 
PDF
Exploring AI Agents in Process Industries
amoreira6
 
Using licensed Data Loss Prevention (DLP) as a strategic proactive data secur...
Q-Advise
 
Activate_Methodology_Summary presentatio
annapureddyn
 
Salesforce Implementation Services Provider.pdf
VALiNTRY360
 
Presentation about variables and constant.pptx
safalsingh810
 
ASSIGNMENT_1[1][1][1][1][1] (1) variables.pptx
kr2589474
 
advancepresentationskillshdhdhhdhdhdhhfhf
jasmenrojas249
 
Why Reliable Server Maintenance Service in New York is Crucial for Your Business
Sam Vohra
 
lesson-2-rules-of-netiquette.pdf.bshhsjdj
jasmenrojas249
 
New Download MiniTool Partition Wizard Crack Latest Version 2025
imang66g
 
Summary Of Odoo 18.1 to 18.4 : The Way For Odoo 19
CandidRoot Solutions Private Limited
 
The-Dawn-of-AI-Reshaping-Our-World.pptxx
parthbhanushali307
 
Visualising Data with Scatterplots in IBM SPSS Statistics.pptx
Version 1 Analytics
 
AI-Ready Handoff: Auto-Summaries & Draft Emails from MQL to Slack in One Flow
bbedford2
 
49784907924775488180_LRN2959_Data_Pump_23ai.pdf
Abilash868456
 
Odoo Integration Services by Candidroot Solutions
CandidRoot Solutions Private Limited
 
GALILEO CRS SYSTEM | GALILEO TRAVEL SOFTWARE
philipnathen82
 
Contractor Management Platform and Software Solution for Compliance
SHEQ Network Limited
 
New Download FL Studio Crack Full Version [Latest 2025]
imang66g
 
ChatPharo: an Open Architecture for Understanding How to Talk Live to LLMs
ESUG
 
Exploring AI Agents in Process Industries
amoreira6
 

Troubleshooting Virtual Threads in Java!

  • 1. 1 © Marwan Abu-Khalil © Marwan Abu-Khalil Page 1 Virtual Threads in Java Scalability and Performance in a new Dimension Marwan Abu-Khalil 2025 1 © Marwan Abu-Khalil Contact [email protected] Marwan Abu-Khalil Senior Software Architect Siemens AG Berlin, Germany www.linkedin.com/in/marwan-abu-khalil Marwan Abu-Khalil Page 2 Seminars § Technische Akademie Esslingen Software Architecture Introduction § iX Workshops, Heise Akademie Software-Architecture Introduction Conference Talks § W-JAX, Munich November 2025: Virtual Threads Workshop § JAX, Mainz Mai 2025: Reactive Streams Workshop Publication on Virtual Threads § Java Spektrum, 2.2025 Virtual Threads in Java: Performance und Skalierbarkeit in neuer Dimension 2
  • 2. 2 © Marwan Abu-Khalil © Marwan Abu-Khalil 1 Understanding Virtual Threads 2 Performance & Scalability 3 Architecture and Blocking Calls 4 Selecting the suitable Concurrency Approach 5 Emerging Language Features 6 Behind the Scenes Agenda Page 4 4 © Marwan Abu-Khalil 1 Understanding Virtual Threads o Motivation o What is a thread? o Mechanics of virtual threads o Benefits of virtual threads o API and usage of virtual threads 2 Performance & Scalability 3 Architecture and Blocking Calls 4 Selecting the suitable Concurrency Approach 5 Emerging Language Features 6 Behind the Scenes Agenda Page 5 Ask your questions in the chat 5
  • 3. 3 © Marwan Abu-Khalil © Marwan Abu-Khalil § Architecture options for concurrent systems o Reality: (simple + synchronous) OR (complex + asynchronous) o Wish: simple + asynchronous § Typical server application: Blocking calls o Blocked threads: Expensive resource wasted § Idea of virtual threads o OS thread released during blocking call Motivation: Scalable Server Applications Page 6 Thread per request: Many clients => many blocking threads within server Not Scalable with classic Platform-Threads 6 © Marwan Abu-Khalil § Thread in general o Path of execution (instruction pointer) o Scheduled and realized by operating system o Memory for stack and CPU-register set § Classic Java Thread is expensive 1. Stack (Memory) 2. OS-Scheduling (CPU) What is a (classic) Thread? Page 7 Number of threads => coexisting simultaneously is limited! 7
  • 4. 4 © Marwan Abu-Khalil © Marwan Abu-Khalil § Virtual Thread M:N Platform-Thread (cheap) o Realized in Java / JVM o Scheduling in Java / JVM (fast) o Temporarily executed by a platform thread o Stack: dynamic § Platform-Thread 1:1 OS-Thread (expensive) o Java Thread: Wrapper around OS-Thread o Scheduled by OS o “Carrier” of Virtual Thread o Stack: static § OS thread (expensive) o Realized by OS o Scheduled by OS Layers and Terms: Virtual-Thread, Platform-Thread (Carrier), OS-Thread Page 8 8 © Marwan Abu-Khalil § Synchronous programming model: Like classic threads § Asynchronous execution: When virtual thread blocks, underlying OS thread gets released § High scalability: Hundreds of thousands … millions Idea of Virtual Threads: Few platform threads run many virtual threads Page 9 Pool of few expensive platform threads: Executes virtual threads 9
  • 5. 5 © Marwan Abu-Khalil © Marwan Abu-Khalil 1. Memory: Static Stack vs. Dynamic Stack § Platform Thread: "expensive" in terms of memory o Fixed-size stack o Assigned at start() § Virtual Thread: cheap in terms of memory o Dynamic Stack of Stack Chunks o Stack chunks allocated as needed at runtime o Swap-In / Swap-Out at mounting / unmounting Virtual Threads: Cheap compared to platform threads Page 10 Risk: Large dynamic stack => advantage gets lost! 2. CPU: Scheduling in “User Mode” § Platform Thread: OS-Scheduling: expensive, slow § Virtual Thread: Scheduling in JVM, without OS, fast Consequence: Non-preemptive scheduling 10 © Marwan Abu-Khalil § Programming model identical to classic Java threads § Platform thread released as soon as virtual thread blocks Key Feature: Automatic release of platform thread in case of blocking Page 11 // Start Thread virtualThread = Thread.startVirtualThread(() -> { System.out.println("Virtual Thread id: " + Thread.currentThread().threadId()); }); // Wait virtualThread.join(); 11
  • 6. 6 © Marwan Abu-Khalil © Marwan Abu-Khalil Blocking – Releasing: Step by Step Page 13 3 2 1 4 5 13 © Marwan Abu-Khalil Synchronous vs. asynchronous programming Page 14 Flux.range(1, 8) // DB Access: 1 Sec blocking .map( and -> readFromDatabase(i)) // Stage decoupling .publishOn(Schedulers.parallel()) .map( list -> computeCPUData(list)) .publishOn(Schedulers.parallel()) .subscribe( list->showInUI(cpuList)); Asynchronous Execution: Reactive Streams for(int i = 1 ; i <= 8; ++i) { final int inputValue = i; Thread thread = new Thread(() ->{ // DB Access: 1 Sec blocking var databaseList = readFromDatabase(inputValue); // CPU: 1 Sec computing var cpuList = computeCPUData(databaseList); // UI showInUI(cpuList); }); thread.start(); } Synchronous: Thread per Request for(int i = 1 ; i <= 8; ++i) { final int arg = i; // Stage 1: DB Access CompletableFuture.supplyAsync(()->readFromDatabase(arg)) // Callback Stage 2: CPU Computation .thenApplyAsync((List<Integer> dbResultSet) -> { return computeCPUData(dbResultSet); }) // Callback Stage 3: UI Rendering .thenAcceptAsync((cpuData) ->{ showInUI(cpuData); }); } Asynchronous Programming: CompletableFutures Simple but inefficient Efficient, but own programming model Complex Programming 14
  • 7. 7 © Marwan Abu-Khalil © Marwan Abu-Khalil Goal § Simple sequential programming o Like classic threads § Efficient asynchronous execution o Wie Reactive Streams Mechanism o OS thread: Release in case of blocking o Asynchrony: Managed automatically Technological background o Mapping Virtual -> Platform-Thread o Operating System asynchronous IO o Non-preemtive scheduling Virtual Threads combine the best of both worlds: Sequential programming + asynchronous execution Page 15 15 © Marwan Abu-Khalil § 1. Why is a platform thread expensive? o Stack: Memory o OS-Scheduling: CPU § 2. Why is a virtual thread cheap? o Dynamic stack o JVM scheduling o Executed by platform thread § 3. What happens when a virtual thread calls a blocking OS operation? o Carrier thread released o Carrier executes other virtual thread o After blocking call returns: Virtual thread runnable Recap (print version) Page 22 22
  • 8. 8 © Marwan Abu-Khalil © Marwan Abu-Khalil What happens when a new virtual thread is created? § Instance of virtual thread is created § New virtual thread mapped to platform thread from pool § Associated platform thread runs virtual thread § Platform thread called "carrier thread" API and usage of virtual threads Page 26 26 © Marwan Abu-Khalil 1. Class Thread 2. ExecutorService (Pool) 3. ThreadBuilder Virtual-Thread extends Thread => Key for simple migration Ways to start a Virtual Thread Page 27 Start: Class Thread Thread virtualThread = Thread.startVirtualThread(() ->{}); Start: ExecutorService Executors.newVirtualThreadPerTaskExecutor().submit(() -> {}); Start: ThreadBuilder Thread.ofVirtual().name("MyVirtualThread").unstarted(() -> {}).start(); 27
  • 9. 9 © Marwan Abu-Khalil © Marwan Abu-Khalil § ExecutorService creation: newVirtualThreadPerTaskExecutor() § Virtual threads never reused § Virtual thread performs one single task, then dies! § Future: Obtain result asynchronously Option 2: Executor Service Page 29 // Pool Interface: ExecutorService ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor(); // Start Future<?> threadResult = executor.submit(() -> { System.out.println("Virtual Thread via Executor ” + Thread.currentThread()); }); // Wait threadResult.get(); 29 © Marwan Abu-Khalil § Virtual threads can be instantiated at ”unlimited” amount o Since they are extremely "cheap" § Reuse is pointless o Virtual threads should never be pooled, they are too cheap o Only platform threads should be pooled (e.g. by ExecutorService) § Beware of "deep stacks" o Performance advantage may be lost o Long running tasks are not good candidates for virtual threads Important Guidlines for using Virtual Threads Page 33 33
  • 10. 10 © Marwan Abu-Khalil © Marwan Abu-Khalil 1 Understanding Virtual Threads 2 Performance & Scalability o Is a Virtual Thread faster? o How can more Concurrency increase Performance? o Examples for Scalability and Performance 3 Architecture and Blocking Calls 4 Selecting the suitable Concurrency Approach 5 Emerging Language Features 6 Behind the Scenes Agenda Page 34 Ask your questions in the chat 34 © Marwan Abu-Khalil NO! Computing speed on CPU is identical!!! § How can virtual threads increase performance? § Virtual threads "only" increase number of simultaneously blocking calls => More simultaneous tasks => More clients at the same time => Higher scalability => Higher throughput => Overall performance improves Is a Virtual Thread faster than a Platform Thread??? Page 35 35
  • 11. 11 © Marwan Abu-Khalil © Marwan Abu-Khalil § Little’s law (John Little, 1954) o Theoretic background for performance increase o Increased concurrency with constant response time implies higher throughput § Modern OS o Can handle many (thousands) simultaneous threads o BUT: Application shoud use few, because they are expensive § Thread Pools provide efficency o Pool size according to number of CPU-cores o Threads kept busy Why is scalabilty a challenge with classic threads? …and how can we gain performance? Page 36 Little’s Law Concurrency => Throughput => Performance! 36 © Marwan Abu-Khalil More simultaneous Clients through Thread Virtualization Page 37 Classic Thread Model Expensive platform threads block during I/O => Few concurrent clients Virtual Thread Model Platform threads always running => Many concurrent clients 37
  • 12. 12 © Marwan Abu-Khalil © Marwan Abu-Khalil § 10,000 Platform-Threads start o After 4000 threads crash: OutOfMemoryError § Alternative: Start 10,000 virtual threads o Runs smoothly § Crucial: blocking OS call (e.g.sleep()) § Effect of Virtual Threads Architecture o Number of parallel tasks massively increased o Little's Law: Throughput increased Example Scalability Page 39 Platform Threads: Crash Virtual Threads: Scale Real limit depends on OS, HW and configuration 39 © Marwan Abu-Khalil § Platform threads start § sleep(): Blocking call § After 4000 threads are started: OutOfMemoryError 10,000 Platform Threads: Crash Page 40 for(int i = 0; i < 1_000_0; ++i) { final int cnt = i; // Launch Platform Thread Thread thread = new Thread(()->{ System.out.println("New OS Thread"+ cnt); // Sleep (blocking call) Thread.sleep(1000); // Exception handling omitted }); thread.start(); } 2 1 Adapt thread count and sleep time to your platform for experiments 3 40
  • 13. 13 © Marwan Abu-Khalil © Marwan Abu-Khalil 10,000 Virtual-Threads: Start easily Page 41 for(int i = 0; i < 10_000; ++i) { final int cnt = i; // Starting virtual thread Thread.startVirtualThread(()->{ System.out.println(”New virtual Thread: " + cnt); sleep(1000); }); } Where does this help? Scalable Server 41 © Marwan Abu-Khalil Performance Example: Increase through virtual threads factor 10!! Page 43 // Variant 1 Platform Threads: 10 seconds, Pool of 1000 Threads //ExecutorService pool = Executors.newFixedThreadPool(1000); // Variant 2 Virtual Threads: 1 second ExecutorService pool = Executors.newVirtualThreadPerTaskExecutor(); long start = System.currentTimeMillis(); for(int i = 0 ; i <= 10_000; ++i) { final int loop_cnt = i; pool.submit(() -> { // Blocking call (exception handling omitted) Thread.sleep(1000); System.out.println("Job " + loop_cnt + " woke up " + (System.currentTimeMillis() - start) / 1000 + " Seconds "); } } One second with 10,000 virtual threads 10 seconds with 1,000 platform threads More simultaneous tasks => Better overall performance 43
  • 14. 14 © Marwan Abu-Khalil © Marwan Abu-Khalil Positive § Higher scalability compared to platform threads § Performance can be massively improved by high scalability (Little's Law) Conclusion on Performance and Scalability of Virtual Threads Page 51 Negative § Blocking calls necessary to profit form virtual threads § Not all architectures, use cases, and systems can benefit from virtual thread migration 51 © Marwan Abu-Khalil 1 Understanding Virtual Threads 2 Performance & Scalability 3 Architecture and Blocking Calls o Rules for Migration o Relevance of blocking Calls o Examples for Scheduling Behavior 4 Selecting the suitable Concurrency Approach 5 Emerging Language Features 6 Behind the Scenes Agenda Page 52 Ask your questions in the chat 52
  • 15. 15 © Marwan Abu-Khalil © Marwan Abu-Khalil 1. Performance limited by amout of available threads o Application could run faster with more threads o Rationale: Virtual threads only add concurrency, not paralleleism, not computing power 2. Significant time spent in blocking OS-calls („IO-Bound“) o Rationale: Virtual threads change system behaviour only during blocking OS-calls Two necessary Pre-Conditions for Performance Gain through Migration to Virtual Threads Page 53 CPU-bound Apps DO NOT BENEFIT!!! except in rare corner cases where context switching is a bottleneck see Quarkus Docu: https://quarkus.io/guides/virtual-threads#cpu-bound 53 © Marwan Abu-Khalil § Typical server application o Significant amount of time: Blocking calls o E.g. database, internal and external services § Thread per Request o Simple to program o Scales only to thread limit of OS § Idea of Virtual Threads o Release OS thread on blocking call o Inside the JVM process: Lock.lock(), Thread.sleep()... o Outside, I/O: Socket, File Access... Relevance and handling of blocking calls (recap) Page 54 54
  • 16. 16 © Marwan Abu-Khalil © Marwan Abu-Khalil § A lot of virtual threads wish to execute sleep() § Single Platform Thread: Executes all virtual threads one at a time § All virtual threads block in sleep(): transferred to unmouted state § sleep() call returns: virtual thread is runnable again Example: Many virtual threads call sleep() at the same time Page 57 57 © Marwan Abu-Khalil § Many (1000) Virtual Threads o Start o Each calls sleep() § Few (8) Platform Threads o Execute 1000 Virtual Threads Output shows: Many virtual threads executed by a few platform threads Page 58 for(int i = 0; i < 1000; ++i) { final int cnt = i; Thread.startVirtualThread(() ->{ System.out.println("Virtual Thread Nr. " + cnt + " " + Thread.currentThread()); // Blocking call releases Carrier-Thread sleep(1000); }); } 1000 Virtual Threads 8 Platform Threads 58
  • 17. 17 © Marwan Abu-Khalil © Marwan Abu-Khalil Scheduler Dynamics: Many Virtual Threads call sleep() 60 © Marwan Abu-Khalil Scenario: Queue of limited size § Many Virtual Threads call take(): blocking § Few Virtual Threads call put(): blocking § Executed by limited size Platform Thread Pool Example: Producer-Consumer with Blocking Queue Page 66 Comparison: Fork-Join-Tasks § May deadlock in queuing scenario § Do not handle blocking efficiently Behavior § Carrier released on blocking take() and put() § All threads run smoothly, no blocking 66
  • 18. 18 © Marwan Abu-Khalil © Marwan Abu-Khalil § 10 virtual threads on 8-core computer, array with 10 slots § Each thread counts up counter in array infinitely § Result: only the first 8 slots are accessed, as only 8 virtual threads run actually § Platform threads instead: All fields in array are incremented Example: Missing preemption changes program semantics Page 69 long[] numbers = new long[10]; // 10 Virtual Threads: // Only 8 array slots processed on 8-Core CPU ExecutorService pool = Executors.newVirtualThreadPerTaskExecutor(); for(int i = 0 ; i < 10; ++i) { final int j = i; pool.execute(() ->{ while(true) { numbers[j]+=1; } }); } sleep(1000); System.out.println(Arrays.toString(numbers)); Rare corner case…. 69 © Marwan Abu-Khalil Virtual threads characteristics § Reuse is pointless o Virtual threads never pooled! o Only platform threads pooled (ExecutorService) § Beware of "deep stacks” o Performance advantage may vanish § No Preemption o Application semantics can change Rules for the use of Virtual Threads and for Migration Recap / Summary Page 71 Migration requires two Pre-Conditions 1. Performance limited by amount of available threads 2. Significant time spent in blocking OS-calls 71
  • 19. 19 © Marwan Abu-Khalil © Marwan Abu-Khalil 1 Understanding Virtual Threads 2 Performance & Scalability 3 Architecture and Blocking Calls 4 Selecting the suitable Concurrency Approach o Reactive Streams comparison o JDK Alternatives: Fork-Join, Parallel Streams 5 Emerging Language Features 6 Behind the Scenes Agenda Page 91 Ask your questions in the chat 91 © Marwan Abu-Khalil Discussions between Reactive Streams and Virtual Threads Advocates § Arguments of virtual thread community (e.g. Brian Getz) o Reactive streams don't fit well into Java Platform o Unit of application's concurrency is pipeline stage o Unit of the platform's concurrency is thread o Tools, stack traces, profilers, debuggers not well usable o "Foreign" programming model: without support in Java language / platform See https://www.infoq.com/articles/java-virtual-threads/ „What About Reactive“ § Argument of ReacitveStreams community (e.g. Thomasz Nurkiewitz) o Only benefit of virtual threads programming model: easy asynchrony o Other Reactive Streams features missing: Backpressure, Change Propagation, Composability See: https://www.infoq.com/presentations/loom-java-concurrency/ Reactive Streams Comparison Page 93 Flux.range(1, 8) // DB Access: 1 Sec blocking .map( and -> readFromDatabase(i)) // Stage decoupling .publishOn(Schedulers.parallel()) .map( list -> computeCPUData(list)) .publishOn(Schedulers.parallel()) .subscribe( list->showInUI(cpuList)); Reactive Streams Example 93
  • 20. 20 © Marwan Abu-Khalil © Marwan Abu-Khalil Virtual Threads § Make IO-bound applications scalable See: Brian Getz, Virtual Threads: new Foundations for Java High Scale Applications https://www.infoq.com/articles/java-virtual-threads/ ForkJoin and ParallelStreams § Ideal for CPU-bound applications o Many asynchronous tasks run on top of few threads § Not suitable for IO bound applications o Blocking OS call not handled well o Blocks underlying pool thread o Risk: Deadlock, or alternatively high memory consumption if pool grows Comparison Virtual-Threads vs. Fork-Join-Tasks & Parallel-Streams Page 94 IO-bound optimized CPU-bound optimized Fork Join Tasks Tech-Stack !"#A%C"'( F*+A%F#,, FJ#,*.%/""0 1/O 1/O P4%45J,.S0,# /*#*00,0T4U#,*9+ !"#$B&'(F*+', -./&(.$0*'"-1O#.-"+-, 1"(U*'(,#+T:T;##*<+ /"F"3+&-(. 4=0'U,#*U"# #"-F*F*+'34/"F" Virtual-Thread Blocking Call 94 © Marwan Abu-Khalil § 2 Virtual Threads run and call put() § Queue full, put() blocks V-T 2 § Carrier thread P-T 2 is freed § P-T 2 now executes V-T 3 § take() frees space in the queue § V-T 2 unblocking § but has no carrier yet Blocking Queue with Virtual Threads Scenario Page 95 95
  • 21. 21 © Marwan Abu-Khalil © Marwan Abu-Khalil § Fork-Join-Tasks o Blocking-Queue: Deadlock § put() blocks when queue full § ForkJoinTasks block Pool-Threads § No more pool threads § No ForkJoinTask runs for take() What fork-join tasks can't do that virtual threads can: e.g. producer-consumer with blocking queue Page 96 96 © Marwan Abu-Khalil Technology selection according to functional and non fuctional properties Page 103 Usecase Virtual Thread Platform Thread Fork-Join-Task Parallel- Stream Reactive- Stream Blocking-IO Yes perfect use-case Yes No Blocks Pool Thread No Blocks Pool Thread Yes Asynchrony System Architecture Structure Yes But focus on server scalabilty Yes Perfect use case No No blocking IO handling No More design level, no blocking IO Yes Many subscribers back-pressure Recursive Algorithm Yes Cheap parallelsim Risk: No preemption Probably not Caution: Memory requirements Yes Perfect Use-Case No Recursion not feasible within pipeline Probably not Focus: distributed concurrent system Pipeline Data Processing Probably not No API support Probably not No API support No No blocking Yes Perfect use-case Yes not primarily for parallelizing pipeline Lots of data infinite streams No Short running Yes Long running No short running No Cannot be partitioned efficiently Yes Perfect use-case API 103
  • 22. 22 © Marwan Abu-Khalil © Marwan Abu-Khalil 1 Understanding Virtual Threads 2 Performance & Scalability 3 Architecture and Blocking Calls 4 Selecting the suitable Concurrency Approach 5 Emerging Language Features o Structured Concurrency o Scoped Values 6 Behind the Scenes Agenda Page 104 Ask your questions in the chat 104 © Marwan Abu-Khalil § Goals o Handle group of virtual threads as single unit o Eliminate concurrent programming risks regarding cancellation and shutdown § Central idea o Combine parallel tasks into a "scope" that succeed or fail together o One thread throws exception: Full “scope” exited § Constructs o StructuredTaskScope: Combines multiple virtual threads into one unit o Subtask<String> subTask1 = scope.fork(() -> {...}): fork starts new Virtual Thread o scope.join(): Waits for all threads in the scope o scope.throwIfFailed(); Terminates scope by an exception when a thread throws errors o StructuredTaskScoped.Joiner: Configures join()-behavioir, e.g. anySuccessfulResultOrThrow() / awaitAll() / awaitAllSuccessfulOrThrow(), https://openjdk.org/jeps/505 (for Java 25) https://openjdk.org/jeps/480 (for Java 23) Structured Concrurency JEP 480, 505, Preview Page 105 Java 25 / Java 23 differences, e.g: public static <T> StructuredTaskScope<T, Void> open() 105
  • 23. 23 © Marwan Abu-Khalil © Marwan Abu-Khalil Structured Concurrency Example (Java 23 Version) Page 106 try(var scope = new StructuredTaskScope.ShutdownOnFailure()){ // Start Subtask Subtask<String> subTask1 = scope.fork(() -> { System.out.println("Task 1 called in " + Thread.currentThread()); return "Hello"; }); // Start Subtask Subtask<String> subTask2 = scope.fork(() -> { for(int i = 0; i < 1000; ++i) { System.out.println("Task 2 loop: " + i +" called in " + Thread.currentThread()); } return ”World"; }); scope.join(); scope.throwIfFailed(); System.out.println(subTask1.get()); System.out.println(subTask2.get()); } Two threads handled as one singe unit wait for all! propagate failures common “scope” bundles virtual threads together 106 © Marwan Abu-Khalil § Idea o ThreadLocal variables optimized for use with virtual threads o Immutable o Cheap o Shared by a hierarchy of virtual threads in a scope (StructuredTaskScope) § Elements o Declaration static final ScopedValue<... > V = ScopedValue.newInstance(); o Setting the value ScopedValue.where(V, <value>) o Binding to lambda expression ScopedValue.run(() -> { ... V.get() ... call methods ... }); o Accessing the value V.get() https://openjdk.org/jeps/487 Scoped Values JEP 487, Preview Page 108 108
  • 24. 24 © Marwan Abu-Khalil © Marwan Abu-Khalil Scoped Values Example Page 109 Declaring Scoped Value static ScopedValue<String> SCOPED_VALUE_EXAMPLE = ScopedValue.newInstance(); Thread virtThread1 = Thread.startVirtualThread(() -> { Bind scoped value with where() and define scope with run() ScopedValue.where(SCOPED_VALUE_EXAMPLE, "Hallo").run(() -> { String valueinThread = SCOPED_VALUE_EXAMPLE.get(); System.out.println("Thread 1: " + valueinThread); }); }); Thread virtThread2 = Thread.startVirtualThread(() -> { Different value in another scope ScopedValue.where(SCOPED_VALUE_EXAMPLE, "GutenTag").run(() -> { String valueinThread = SCOPED_VALUE_EXAMPLE.get(); System.out.println("Thread 2: " + valueinThread); }); }); single instance Assign value for thread 1 other value for thread 2 different outputs Core feature: Anywhere in the code available without argument 109 © Marwan Abu-Khalil 1 Understanding Virtual Threads 2 Performance & Scalability 3 Architecture and Blocking Calls 4 Selecting the suitable Concurrency Approach 5 Emerging Language Features 6 Behind the Scenes o JVM Virtual Threads Architecture o Consequences for Application Design Agenda Page 110 Ask your questions in the chat 110
  • 25. 25 © Marwan Abu-Khalil © Marwan Abu-Khalil 1. Blocking call: Carrier Thread released § M:N Mapping: Virtual thread run by several platform threads § New carrier after blocking call 2. Dynamic Stack § Stack can grow and shrink (StackChunk objects, lazy-loading) § Mounting / unmounting: Stack-frames copied from carrier's stack to heap (& vice versa) 3. Continuations § Virtual threads are realized as “continuations” § “one shot delimited continuations” theoretic concept behind 4. User Mode Scheduling § No preemption: A virtual thread runs to completion Architecture of virtual threads = > Consequences for App Design and Behavior Page 111 Changed program semantics, e.g. starvation Cheap scheduling Beware of deep stacks Memory saving Only IO-bound apps benefit Performance optimization Easy migration Automatic asynchrony 111 © Marwan Abu-Khalil Conclusion on Virtual Threads Page 114 Positive § Extremely highly scalable o Many thousands of simultaneous tasks § Massive performance boost possible o Throughput o Little’s Law § Saved resources o Memory and CPU o Platform Threads § Simple programming model o Like classic threads o Easy migration o Sequential programming, asych. execution Carefully consider before migration § Only effective with significant blocking time o Blocking time per client call relevant o Only for IO bound applications o No benefit for computationally intensive applications § High degree of concurrency required o Unreachable with platform threads o Thousands, possibly millions § Semantic change possible (rare case!) o No preemption 114
  • 26. 26 © Marwan Abu-Khalil © Marwan Abu-Khalil 1 Understanding Virtual Threads 2 Performance & Scalability 3 Architecture and Blocking Calls 4 Selecting the suitable Concurrency Approach 5 Emerging Language Features 6 Behind the Scenes Agenda in Retrospect Page 115 115 © Marwan Abu-Khalil - Oracle Java Core Libraries Documentation: https://docs.oracle.com/en/java/javase/21/core/virtual-threads.html - JEP Virtual Threads https://openjdk.org/jeps/425 and https://openjdk.org/jeps/444 - JEP Structured Concurrency: https://openjdk.org/jeps/453, https://openjdk.org/jeps/505 - Brian Getz, 2022: New Foundations for Java High Scale Applications https://www.infoq.com/articles/java-virtual- threads/ - Michael Inden, 2025: Java 21 LTS bis 24 -- Coole neue Java-Features: Modernes Java leicht gemacht https://amzn.eu/d/2FrSinA - Sven Woltmann, 2022, nice little examples: https://www.happycoders.eu/de/java/virtual-threads/ - Nicolai Parlog, Oracle, 2022: https://blogs.oracle.com/javamagazine/post/java-loom-virtual-threads-platform-threads - Lutz Hühnken, entwickler.de 2020 https://entwickler.de/java/blick-in-die-fernere-zukunft - Reinald Menge-Sonntag, heise online 2022: https://www.heise.de/news/Java-19-verbessert-die-Nebenlaeufigkeit-mit-virtuellen- Threads-aus-Project-Loom-7269453.html - Ron Presler, QCon 2019: https://www.infoq.com/presentations/continuations-java/ - Thomasz Nurkiewitz, QCon 2022: https://www.infoq.com/presentations/loom-java-concurrency/ - Ricardo Cardin, 2023, good Examples about Threadpool and Scheduling: https://blog.rockthejvm.com/ultimate- guide-to-java-virtual-threads/#3-how-to-create-a-virtual-thread - Marwan Abu-Khalil, 2025 , Virtual Threads in Java: Performance und Skalierbarkeit in neuer Dimension, https://www.sigs.de/artikel/virtual-threads-in-java-performance-und-skalierbarkeit-in-neuer-dimension/ Literature and web links (some are in German, but still great!) Page 116 116
  • 27. 27 © Marwan Abu-Khalil © Marwan Abu-Khalil Contact [email protected] Marwan Abu-Khalil Senior Software Architect Siemens AG Berlin, Germany www.linkedin.com/in/marwan-abu-khalil Marwan Abu-Khalil Page 117 Seminars § Technische Akademie Esslingen Software Architecture Introduction § iX Workshops, Heise Akademie Software-Architecture Introduction Conference Talks § W-JAX, Munich November 2025: Virtual Threads Workshop § JAX, Mainz Mai 2025: Reactive Streams Workshop Publication on Virtual Threads § Java Spektrum, 2.2025 Virtual Threads in Java: Performance und Skalierbarkeit in neuer Dimension 117 © Marwan Abu-Khalil Page 118 Q&A Ask your QUESTIONS in the chat! 118