Java 的线程模型一直是高并发系统的核心。传统平台线程(Platform Thread)与操作系统线程 1:1 映射,创建成本高、内存占用大,导致开发者不得不依赖线程池、异步回调和响应式编程来提升吞吐。但这也带来了回调地狱、上下文丢失、调试困难等问题。
Java 21 正式引入虚拟线程(Virtual Thread),并预览结构化并发(Structured Concurrency),目标很明确:让开发者用同步阻塞的写法,获得高并发的吞吐。
虚拟线程由 JVM 调度,多个虚拟线程映射到少量平台线程上,属于 M:N 模型。它适合 IO 密集型任务,比如 HTTP 调用、数据库查询、文件读写。
创建虚拟线程:
Thread vThread = Thread.ofVirtual()
.name("v-thread-", 0)
.start(() -> {
System.out.println("Running in virtual thread: " + Thread.currentThread());
});
vThread.join();更常用的方式是使用每任务一个虚拟线程的执行器:
import java.time.Duration;
import java.util.concurrent.Executors;
import java.util.stream.IntStream;
public class VirtualThreadDemo {
public static void main(String[] args) {
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
IntStream.range(0, 10_000).forEach(i -> executor.submit(() -> {
Thread.sleep(Duration.ofSeconds(1));
return i;
}));
} // 自动 close,等待任务结束
}
}这段代码创建 1 万个虚拟线程,每个睡 1 秒。传统平台线程下,这可能需要大量内存和线程池调优;虚拟线程则可以轻松承载。
虚拟线程不是银弹:
Semaphore 控制并发。import java.util.concurrent.Semaphore;
public class RateLimitedService {
private final Semaphore semaphore = new Semaphore(100);
public String call() throws InterruptedException {
semaphore.acquire();
try {
return remoteCall();
} finally {
semaphore.release();
}
}
private String remoteCall() throws InterruptedException {
Thread.sleep(200);
return "ok";
}
}结构化并发把一组相关任务视为一个工作单元:要么全部成功,要么一起失败,避免线程泄漏和任务失控。Java 21 中 StructuredTaskScope 是预览 API,需要 --enable-preview。
import java.util.concurrent.StructuredTaskScope;
import java.util.function.Supplier;
public class UserService {
public Response load() throws Exception {
try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
Supplier<String> user = scope.fork(this::fetchUser);
Supplier<String> order = scope.fork(this::fetchOrder);
scope.join(); // 等待所有子任务
scope.throwIfFailed(); // 任一失败则抛出
return new Response(user.get(), order.get());
}
}
private String fetchUser() throws InterruptedException {
Thread.sleep(100);
return "user";
}
private String fetchOrder() throws InterruptedException {
Thread.sleep(150);
return "order";
}
public record Response(String user, String order) {}
}ShutdownOnFailure 会在任一子任务失败时取消其他任务,避免资源浪费。还有 ShutdownOnSuccess,适合“最快成功即可”的场景。
spring.threads.virtual.enabled=true 启用虚拟线程;ReentrantLock;虚拟线程让 Java 高并发回归简单:用同步代码写异步吞吐。结构化并发则让并发任务具备生命周期和失败传播,减少线程泄漏。两者结合,是 Java 21 之后服务端开发的重要方向。但工程落地仍需关注限流、监控、下游容量和框架兼容性。工具越强,边界越要清晰。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。