Skip to content

Java 多线程与并发指南 (包含虚拟线程)

Java 提供了强大的多线程支持。在 2026 年的现代 Java 开发中,除了传统的平台线程(Platform Threads)与线程池,基于 Project Loom 引入的 虚拟线程 (Virtual Threads) 已经成为了构建高并发应用的首选。

传统线程在操作系统级别会映射为一个原生线程,具有较高的创建开销。

  1. 实现 Runnable 接口
    public class Main {
    public static void main(String[] args) {
    Thread thread = new Thread(() -> {
    System.out.println("平台线程运行中...");
    });
    thread.start();
    }
    }

虚拟线程是轻量级的线程,由 JVM 进行调度,不直接绑定到操作系统的原生线程。这使得我们在单机上可以轻松创建数以百万计的线程,而不会耗尽内存或导致上下文切换的性能灾难。

public class VirtualThreadDemo {
public static void main(String[] args) throws InterruptedException {
// 使用 Thread.ofVirtual() 创建并启动
Thread vThread = Thread.ofVirtual().start(() -> {
System.out.println("虚拟线程执行中: " + Thread.currentThread());
});
vThread.join();
}
}

2. 使用虚拟线程池 (结构化并发)

Section titled “2. 使用虚拟线程池 (结构化并发)”

在现代 Java 中,通常推荐使用 Executors.newVirtualThreadPerTaskExecutor(),它会为每个任务启动一个全新的虚拟线程,无需像过去那样使用复杂的池化技术。

try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
for (int i = 0; i < 100_000; i++) {
final int taskId = i;
executor.submit(() -> {
// 模拟阻塞 I/O,虚拟线程在阻塞时会主动让出底层平台线程
Thread.sleep(1000);
System.out.println("完成任务 " + taskId);
return taskId;
});
}
} // try-with-resources 会自动等待所有虚拟线程执行完毕

无论是平台线程还是虚拟线程,访问共享资源时都需要同步。

  1. synchronized 关键字

    class Counter {
    private int count = 0;
    public synchronized void increment() { count++; }
    }

    注意:在早期的 Java 版本中,虚拟线程在 synchronized 块内进行 I/O 阻塞会导致底层平台线程被 “Pinning” (固定),但在 Java 25 左右该问题已被彻底优化。

  2. ReentrantLock: 提供了比 synchronized 更灵活的锁机制。

在 2026 年,Java 并发编程的范式已经发生了彻底的转变:

  • 对于 CPU 密集型任务,继续使用传统的 ForkJoinPool 或固定大小的线程池。
  • 对于 I/O 密集型任务(如数据库查询、网络请求),无脑使用 虚拟线程 (Virtual Threads),彻底告别复杂的回调地狱和响应式编程(如 WebFlux)。