一、线程创建核心方式对比
| 创建方式 | 特点 | 适用场景 | JDK版本 |
|---|---|---|---|
继承Thread类 | 简单但缺乏扩展性 | 快速原型开发 | 1.0+ |
实现Runnable接口 | 解耦任务与执行 | 线程池任务提交 | 1.0+ |
实现Callable+Future | 支持返回值与异常抛出 | 需要获取异步结果 | 5.0+ |
线程池(ExecutorService) | 资源复用,管理精细化 | 高并发服务 | 5.0+ |
CompletableFuture | 异步编排,函数式编程 | 复杂任务链 | 8.0+ |
虚拟线程(VirtualThread) | 轻量级,支持百万级并发 | I/O密集型高吞吐 | 19+ (Loom) |
二、6种线程创建方式详解
1. 继承Thread类(基础版)
class MyThread extends Thread {
@Override
public void run() {
System.out.println("Thread ID: " + Thread.currentThread().getId());
}
}
// 启动线程
new MyThread().start();
缺点:
-
单继承限制,无法继承其他类
-
任务与执行机制耦合
2. 实现Runnable接口(推荐基础方案)
class Task implements Runnable {
@Override
public void run() {
System.out.println("执行任务: " + LocalDateTime.now());
}
}
// 使用方式
new Thread(new Task()).start();
// 或提交到线程池
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(new Task());
3. 实现Callable+Future(带返回值)
class ComputeTask implements Callable<Integer> {
@Override
public Integer call() throws Exception {
TimeUnit.SECONDS.sleep(1);
return ThreadLocalRandom.current().nextInt(100);
}
}
// 获取结果
ExecutorService executor = Executors.newCachedThreadPool();
Future<Integer> future = executor.submit(new ComputeTask());
Integer result = future.get(); // 阻塞获取结果
4. 线程池创建(生产环境推荐)
// 自定义线程池(避免使用Executors)
ThreadPoolExecutor executor = new ThreadPoolExecutor(
4, // 核心线程数
8, // 最大线程数
60, TimeUnit.SECONDS,
new ArrayBlockingQueue<>(100),
new ThreadFactory() { // 自定义线程命名
private AtomicInteger count = new AtomicInteger(1);
public Thread newThread(Runnable r) {
return new Thread(r, "Worker-" + count.getAndIncrement());
}
},
new ThreadPoolExecutor.CallerRunsPolicy()
);
// 提交任务
executor.execute(() -> System.out.println("Task running in pool"));
5. CompletableFuture(异步编程利器)
// 链式调用示例
CompletableFuture.supplyAsync(() -> fetchUserData())
.thenApplyAsync(data -> processData(data))
.thenAcceptAsync(result -> saveResult(result))
.exceptionally(ex -> {
System.err.println("Error: " + ex.getMessage());
return null;
});
// 自定义线程池
ExecutorService customPool = Executors.newWorkStealingPool();
CompletableFuture.runAsync(() -> heavyCompute(), customPool);
6. 虚拟线程(Project Loom - JDK19+)
// 创建虚拟线程(轻量级)
Thread virtualThread = Thread.ofVirtual()
.name("VT-1")
.unstarted(() -> {
System.out.println("Running in virtual thread");
});
virtualThread.start();
// 使用线程池
ExecutorService vtExecutor = Executors.newVirtualThreadPerTaskExecutor();
vtExecutor.submit(() -> ioIntensiveTask());
三、生产环境最佳实践
1. 线程创建黄金原则
-
禁止直接
new Thread:使用线程池统一管理 -
线程命名规范:通过
ThreadFactory明确标识(如Order-Processor-1) -
异常处理:为线程池设置
UncaughtExceptionHandler
ThreadFactory factory = r -> {
Thread t = new Thread(r);
t.setUncaughtExceptionHandler((thread, ex) -> {
logger.error("Thread {} failed: {}", thread.getName(), ex);
});
return t;
};
2. 资源关闭策略
// 使用try-with-resources自动关闭
try (ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor()) {
executor.submit(() -> criticalTask());
} // 自动调用shutdown()
3. 性能对比数据
| 方式 | 10万任务耗时 | 内存占用(MB) | 线程数上限 |
|---|---|---|---|
| 传统线程 | 38s | 2048 | ~4000 |
| 固定线程池(4核) | 12s | 256 | 4 |
| 虚拟线程 | 9s | 128 | 1,000,000 |
四、常见问题解决方案
1. 线程池任务堆积
-
现象:
RejectedExecutionException -
解决:
-
调整队列容量(
new LinkedBlockingQueue(1000)) -
使用有界队列+拒绝策略(如
ThreadPoolExecutor.DiscardOldestPolicy)
-
2. 线程泄漏
-
检测:通过
JMX监控线程数持续增长 -
预防:
-
确保
finally块中释放资源 -
使用
ThreadPoolExecutor而非newCachedThreadPool()
-
3. 上下文切换开销
-
优化:
-
I/O密集型任务使用虚拟线程
-
减少锁竞争(使用
ConcurrentHashMap代替synchronizedMap)
-
五、线程创建方式选择决策树

结语
根据业务场景灵活选择线程创建方式:
-
简单异步 →
CompletableFuture -
批量任务 →
ThreadPoolExecutor -
超高并发 → 虚拟线程(JDK19+)
-
遗留系统 →
Runnable+线程池
1032

被折叠的 条评论
为什么被折叠?



