---
title:
description: Java 21 Virtual Threads Spring Boot
category: Java
tag:
- Java
head:
- - meta
- name: keywords
content: Java,Virtual Threads,Project Loom,Java 21,,,
---
Web I/O
I/O
##
Virtual Thread Java 21 `java.lang.Thread` JDK
Platform Thread Java JDK
Java
- `Thread` `ThreadLocal` JFR
- HTTP I/O
- CPU
-
##
Java

WindowsLinux HotSpot JVM JDK
- `Thread.currentThread()`
- Carrier Thread Java
-
JDK mount I/O`BlockingQueue.take()``Future.get()` unmount
```java
String body = httpClient.send(request, BodyHandlers.ofString()).body();
Result result = repository.query(body);
return service.handle(result);
```
## Project Loom
Project Loom OpenJDK Java Loom JDK 19JDK 20 [JEP 444](https://openjdk.org/jeps/444) JDK 21
Loom API JDK I/OJFR thread-per-request I/O
Java ProfilerJFR dump
##
dump
50ms 2000 QPS Little's Law 100 500ms 2000 QPS 1000 CPU
Reactive I/O `CompletableFuture`
##
-
- I/ORedisHTTP/RPC
-
-
- Spring MVC / Servlet HTTP
-
-
-
CPU CPU CPU
##
JDK 21
### `Thread.startVirtualThread()`
```java
public class VirtualThreadDemo {
public static void main(String[] args) throws InterruptedException {
Thread thread = Thread.startVirtualThread(() -> {
System.out.println(Thread.currentThread());
});
thread.join();
}
}
```
`main` JVM
### `Thread.ofVirtual()`
`Thread.ofVirtual()` `Thread.Builder.OfVirtual`
```java
public class VirtualThreadDemo {
public static void main(String[] args) throws InterruptedException {
Thread unstarted = Thread.ofVirtual()
.name("order-query")
.unstarted(() -> System.out.println("query order"));
unstarted.start();
unstarted.join();
Thread started = Thread.ofVirtual()
.name("payment-query")
.start(() -> System.out.println("query payment"));
started.join();
}
}
```
### `ThreadFactory`
`ThreadFactory`
```java
import java.util.concurrent.ThreadFactory;
public class VirtualThreadDemo {
public static void main(String[] args) throws InterruptedException {
ThreadFactory factory = Thread.ofVirtual()
.name("worker-", 0)
.factory();
Thread thread = factory.newThread(() -> {
System.out.println(Thread.currentThread().getName());
});
thread.start();
thread.join();
}
}
```
### `Executors.newVirtualThreadPerTaskExecutor()`
```java
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class VirtualThreadDemo {
public static void main(String[] args) throws Exception {
try (ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor()) {
Future future = executor.submit(() -> {
return "hello virtual thread";
});
System.out.println(future.get());
}
}
}
```
`ExecutorService` `try-with-resources` `close()`
##
20 `Semaphore`
```java
import java.util.concurrent.Semaphore;
public class OldServiceClient {
private static final Semaphore LIMIT = new Semaphore(20);
public String call() throws InterruptedException {
LIMIT.acquire();
try {
return doCall();
} finally {
LIMIT.release();
}
}
private String doCall() {
return "ok";
}
}
```
CPU
##
I/O HTTP
10,000 1
```java
import java.time.Duration;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.IntStream;
public class VirtualThreadCompareDemo {
public static void main(String[] args) {
long start = System.currentTimeMillis();
try (ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor()) {
IntStream.range(0, 10_000).forEach(i -> {
executor.submit(() -> {
Thread.sleep(Duration.ofSeconds(1));
return i;
});
});
}
System.out.println("cost: " + (System.currentTimeMillis() - start) + "ms");
}
}
```
`Executors.newFixedThreadPool(200)` 200 10,000 1 50 10,000
HTTP GC CPU
##
/
###
JDK JEP 444 FIFO work-stealing `ForkJoinPool` common pool
- `jdk.virtualThreadScheduler.parallelism`
- `jdk.virtualThreadScheduler.maxPoolSize`
###
Java
JDK I/O`BlockingQueue``Future.get()`
JDK 21 JDK 23 `synchronized` PinningJDK 24 [JEP 491](https://openjdk.org/jeps/491) `synchronized` `synchronized` Pinning native Foreign Function & Memory API Pinning
###
Java
`ThreadLocal`
## Pinning
Pinning
JDK 21 JDK 23 Pinning `synchronized` I/O
```java
public synchronized String load() throws IOException {
return remoteClient.get("/config"); // JDK 21-23
}
```
`synchronized` I/O
JDK 21 JDK 23
- `synchronized` I/O
- `ReentrantLock` `try/finally`
- JFR `jdk.VirtualThreadPinned`
- `-Djdk.tracePinnedThreads=full`
JDK 24 `synchronized` Pinning JEP 491 `synchronized` `java.util.concurrent.locks`
##
### CPU
CPU CPU CPU
###
`Semaphore`
### `ThreadLocal`
Java 21 `ThreadLocal` `ThreadLocal`
`ThreadLocal`
IDTrace ID formatterJDK 25 JEP 506 Scoped Values
###
###
HTTP Redis
- QPS
-
- HTTP 429/5xx
- CPUGC
- JFR
###
Reactive/WebFlux/Netty
## Spring Boot
Spring Boot 3.2 Java 21
```properties
spring.threads.virtual.enabled=true
```
Spring Boot
- JVM
- `@Scheduled` JVM `spring.main.keep-alive=true`
- Spring Boot Java 24 Pinning
```yaml
spring:
threads:
virtual:
enabled: true
main:
keep-alive: true
```
I/O CPU SQL
##
JDK
### `jcmd`
`jstack` JDK
```bash
jcmd Thread.dump_to_file -format=json thread-dump.json
```
```bash
jcmd Thread.dump_to_file -format=text thread-dump.txt
```
JSON
### JFR
JFR
- `jdk.VirtualThreadStart`
- `jdk.VirtualThreadEnd`
- `jdk.VirtualThreadPinned`
- `jdk.VirtualThreadSubmitFailed`
`jdk.VirtualThreadPinned` Pinning JDK 24 `synchronized` Pinning native/FFM JFR
### Pinning
JDK 21 JDK 23
```bash
-Djdk.tracePinnedThreads=full
```
JDK 24 JEP 491 `synchronized` Pinning native/FFM JFR
##
###
JDK I/O
### I/O
I/O
### CPU
CPU CPU CPU
###
HTTP `Semaphore`
###
Java `java.lang.Thread` Java `async/await` yield Go goroutine Java API
### Reactive
Reactive
### JDK 21 `synchronized`
JDK 21 JDK 23 `synchronized` Pinning `synchronized` I/OJDK 24 JEP 491 `synchronized` Pinning
##
- [JEP 444: Virtual Threads](https://openjdk.org/jeps/444)
- [Oracle Java 21 Documentation: Virtual Threads](https://docs.oracle.com/en/java/javase/21/core/virtual-threads.html)
- [JEP 491: Synchronize Virtual Threads without Pinning](https://openjdk.org/jeps/491)
- [JEP 506: Scoped Values](https://openjdk.org/jeps/506)
- [Spring Boot Reference Documentation: Virtual threads](https://docs.spring.io/spring-boot/reference/features/spring-application.html#features.spring-application.virtual-threads)
- [Spring Blog: Embracing Virtual Threads](https://spring.io/blog/2022/10/11/embracing-virtual-threads/)
- [Inside Java: Managing Throughput with Virtual Threads](https://inside.java/2024/02/04/sip094/)
- [Quarkus Blog: When Quarkus meets Virtual Threads](https://quarkus.io/blog/virtual-thread-1/)