JDK 8、JDK 17 和 JDK 21 中 Java 多线程实现方式总结(2025 最新全网最全教程)

本文针对 JDK 8、JDK 17 和 JDK 21 在 Java 多线程实现方式上的演进进行梳理,逐版本展示典型用法,深入对比优缺点和适用场景,帮助你快速选型。


引言

在 Java 生态中,多线程一直是构建高并发、高性能应用的核心手段。从最早的 Thread 类和 Runnable 接口到最新的虚拟线程与结构化并发,不同 JDK 版本不断丰富和简化编程模型。本篇博客将分三个阶段(JDK 8、JDK 17、JDK 21)深入剖析各种方案的用法、优缺点及适用场景。


Java 多线程演进示意图


目录

  1. JDK 8:经典多线程方案

    1. 继承 Thread
    2. 实现 Runnable 接口
    3. 使用 Callable + Future
    4. 基于 ExecutorService 的线程池
  2. JDK 17:异步与并行编程利器

    1. CompletableFuture
    2. 并行流(Parallel Stream)
    3. 增强的线程池用法
  3. JDK 21:虚拟线程与结构化并发

    1. 虚拟线程(Virtual Threads)
    2. 结构化并发(Structured Concurrency)
  4. 特性对比与选型建议

  5. Mermaid 可视化概览

  6. 结语


JDK 8 经典多线程方案

1. 继承 Thread

class MyThread extends Thread {
    @Override
    public void run() {
        for (int i = 1; i <= 20; i++) {
            System.out.println("[Thread] 计数:" + i);
        }
    }
}

public class TestThread {
    public static void main(String[] args) {
        MyThread t = new MyThread();
        t.start();  // 启动新线程,执行 run()
        for (int i = 1; i <= 20; i++) {
            System.out.println("[Main] 计数:" + i);
        }
    }
}
  • 优点:使用简单,上手快。
  • 缺点:Java 单继承,线程类无法再扩展其他类;任务与线程耦合;无返回值。

2. 实现 Runnable 接口

class MyTask implements Runnable {
    @Override
    public void run() {
        for (int i = 1; i <= 20; i++) {
            System.out.println("[Runnable] 计数:" + i);
        }
    }
}

public class TestRunnable {
    public static void main(String[] args) {
        Thread t = new Thread(new MyTask());
        t.start();
        for (int i = 1; i <= 20; i++) {
            System.out.println("[Main] 计数:" + i);
        }
    }
}
  • 优点:任务与线程分离,可复用任务类;可多继承其他类。
  • 缺点:无返回值;需手动管理线程对象。

3. 使用 Callable + Future

import java.util.concurrent.*;

public class TestCallable {
    public static void main(String[] args) throws Exception {
        Callable<Integer> c = () -> {
            int sum = 0;
            for (int i = 1; i <= 50; i++) sum += i;
            return sum;
        };

        FutureTask<Integer> future = new FutureTask<>(c);
        Thread t = new Thread(future);
        t.start();
        Integer result = future.get();  // 阻塞等待
        System.out.println("sum = " + result);
    }
}
  • 优点:支持返回值和异常。
  • 缺点:相对复杂,需要手动包装。

4. 基于 ExecutorService 的线程池

import java.util.concurrent.*;

public class TestThreadPool {
    public static void main(String[] args) {
        ExecutorService pool = Executors.newFixedThreadPool(2);

        Runnable task = () -> {
            for (int i = 1; i <= 20; i++) {
                System.out.println("[Pool] 计数:" + i);
            }
        };

        pool.submit(task);
        pool.shutdown();
    }
}
  • 优点:线程可复用,避免频繁创建销毁;灵活配置线程池参数。
  • 缺点:JDK 8 的 Executors 工厂方法对队列、拒绝策略等缺乏精细控制。

JDK 17 异步与并行编程利器

1. CompletableFuture

import java.util.concurrent.*;

public class TestCompletableFuture {
    public static void main(String[] args) throws Exception {
        CompletableFuture<Integer> f1 = CompletableFuture.supplyAsync(() -> {
            int sum = 0;
            for (int i = 1; i <= 50; i++) sum += i;
            return sum;
        });

        CompletableFuture<Integer> f2 = CompletableFuture.supplyAsync(() -> {
            int sum = 0;
            for (int i = 51; i <= 100; i++) sum += i;
            return sum;
        });

        Integer total = f1.thenCombine(f2, Integer::sum).get();
        System.out.println("total = " + total);
    }
}
  • 优点:链式编程、异常处理、非阻塞、可组合。
  • 缺点:API 学习曲线稍陡;链式过长略显冗余。

2. 并行流(Parallel Stream)

import java.util.stream.IntStream;

public class TestParallelStream {
    public static void main(String[] args) {
        int total = IntStream.rangeClosed(1, 100)
                             .parallel()    // 并行执行
                             .sum();
        System.out.println("parallel sum = " + total);
    }
}
  • 优点:一行代码开启多核并行计算。
  • 缺点:适合无状态数据处理;I/O、状态更新场景需谨慎。

3. 增强的线程池用法

ThreadPoolExecutor pool = new ThreadPoolExecutor(
    4,                      // corePoolSize
    8,                      // maximumPoolSize
    60L, TimeUnit.SECONDS,  // keepAliveTime
    new LinkedBlockingQueue<>(100),
    new ThreadPoolExecutor.CallerRunsPolicy()
);
  • 优点:可精细控制队列、拒绝策略。
  • 缺点:参数较多,需要根据业务调优。

JDK 21 虚拟线程与结构化并发

1. 虚拟线程(Virtual Threads)

public class TestVirtualThread {
    public static void main(String[] args) throws InterruptedException {
        // 创建并启动 1000 个虚拟线程
        for (int i = 0; i < 1000; i++) {
            Thread.startVirtualThread(() -> {
                System.out.println(Thread.currentThread() + " 执行任务");
            });
        }
        Thread.sleep(1000); // 等待所有任务完成
    }
}
  • 优点:开销极低,可轻松支持数万/百万并发;与传统线程一致的编程模型。
  • 缺点:少数老库对 ThreadLocal 兼容性需验证。

2. 结构化并发(Structured Concurrency)

import java.util.concurrent.*;
import jdk.incubator.concurrent.StructuredTaskScope;

public class TestStructuredConcurrency {
    public static void main(String[] args) throws Exception {
        try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
            Future<Integer> f1 = scope.fork(() -> computeSum(1, 50));
            Future<Integer> f2 = scope.fork(() -> computeSum(51, 100));

            scope.join();          // 等待所有子任务完成
            scope.throwIfFailed(); // 失败即抛

            int total = f1.resultNow() + f2.resultNow();
            System.out.println("structured total = " + total);
        }
    }

    static int computeSum(int a, int b) {
        int s = 0;
        for (int i = a; i <= b; i++) s += i;
        return s;
    }
}
  • 优点:任务生命周期与作用域绑定;自动管理一组任务的失败和取消。
  • 缺点:需导入孵化模块;API 仍在演进。

特性对比与选型建议

特性/版本 JDK 8 JDK 17 JDK 21
线程模型 平台线程 平台线程 平台线程 + 虚拟线程
任务定义 Thread/Runnable/Callable CompletableFuture/并行流 虚拟线程 + 结构化并发
返回 & 异常 FutureTask CompletableFuture 同 JDK 17 + 结构化异常管理
可扩展性 手动调优线程池 并行流 & 异步易扩展 数万线程无忧;任务隔离更优
使用复杂度 中等(API 零散) 较高(链式 API),易错 简洁(虚拟线程 & 统一模型)
最佳场景 少量固定线程、简单并发 异步组合、批量并行计算 超高并发 I/O 密集型服务
  • JDK 8:优先使用线程池,避免频繁创建和销毁;需返回值请选择 Callable
  • JDK 17:推荐 CompletableFuture 构建异步流水线,并行流做大数据批量计算,必要时手动配置 ThreadPoolExecutor
  • JDK 21:立即试用虚拟线程消除数量瓶颈;对复杂任务组使用结构化并发获得更安全的失败语义。

Mermaid 可视化概览

JDK 8
Thread / Runnable
Callable + Future
ExecutorService
JDK 17
CompletableFuture
Parallel Stream
Enhanced ThreadPool
JDK 21
Virtual Threads
Structured Concurrency

结语

Java 多线程模型历经十余年演进,从原始的 ThreadRunnable,到现代的异步及大规模并发支持。了解各版本特性,结合业务需求与性能指标,才能设计出既稳定又高效的并行系统。希望本篇博客能助你在 JDK 8、JDK 17、JDK 21 的多线程世界里游刃有余,写出既简洁又强悍的并行代码。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐