在 Java 中,实现和管理线程池有多种方式。以下是几种常见的方式,包括使用 Executors
工具类、直接使用 ThreadPoolExecutor
、自定义线程池等。
1. 使用 Executors 工具类
Executors
工具类提供了几种便捷的方法来创建常见类型的线程池:
1.1 固定大小线程池 (Fixed Thread Pool)
适用于需要固定数量线程处理任务的场景。
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(4);
// 提交任务到线程池
fixedThreadPool.submit(() -> {
// 任务逻辑
});
// 关闭线程池
fixedThreadPool.shutdown();
1.2 缓存线程池 (Cached Thread Pool)
适用于大量短生命周期任务的场景,线程池大小根据需要自动调整。
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
// 提交任务到线程池
cachedThreadPool.submit(() -> {
// 任务逻辑
});
// 关闭线程池
cachedThreadPool.shutdown();
1.3 单线程池 (Single Thread Executor)
确保任务按顺序执行,只有一个线程。
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
// 提交任务到线程池
singleThreadExecutor.submit(() -> {
// 任务逻辑
});
// 关闭线程池
singleThreadExecutor.shutdown();
1.4 调度线程池 (Scheduled Thread Pool)
用于周期性或定时执行任务。
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(2);
// 提交延时任务
scheduledThreadPool.schedule(() -> {
// 任务逻辑
}, 5, TimeUnit.SECONDS);
// 提交周期性任务
scheduledThreadPool.scheduleAtFixedRate(() -> {
// 任务逻辑
}, 0, 10, TimeUnit.SECONDS);
// 关闭线程池
scheduledThreadPool.shutdown();
2. 直接使用 ThreadPoolExecutor
ThreadPoolExecutor
提供了更高级的线程池配置选项,适用于需要高度定制的场景。
2.1 使用 ThreadPoolExecutor 创建线程池
int corePoolSize = 2;
int maximumPoolSize = 4;
long keepAliveTime = 10;
TimeUnit unit = TimeUnit.SECONDS;
BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(2);
RejectedExecutionHandler handler = new ThreadPoolExecutor.CallerRunsPolicy();
ExecutorService threadPool = new ThreadPoolExecutor(
corePoolSize,
maximumPoolSize,
keepAliveTime,
unit,
workQueue,
Executors.defaultThreadFactory(),
handler);
// 提交任务到线程池
threadPool.submit(() -> {
// 任务逻辑
});
// 关闭线程池
threadPool.shutdown();
3. 自定义线程池
您可以通过实现 ThreadFactory
接口或自定义 RejectedExecutionHandler
来创建更复杂的线程池行为。
3.1 自定义 ThreadFactory
用于定制新创建线程的属性,比如名称、优先级等。
ThreadFactory customThreadFactory = new ThreadFactory() {
private final AtomicInteger threadNumber = new AtomicInteger(1);
@Override
public Thread newThread(Runnable r) {
Thread thread = new Thread(r);
thread.setName("CustomThread-" + threadNumber.getAndIncrement());
thread.setPriority(Thread.NORM_PRIORITY);
return thread;
}
};
ExecutorService customThreadPool = new ThreadPoolExecutor(
2,
4,
60L,
TimeUnit.SECONDS,
new SynchronousQueue<>(),
customThreadFactory);
customThreadPool.submit(() -> {
// 任务逻辑
});
customThreadPool.shutdown();
3.2 自定义 RejectedExecutionHandler
用于定制任务被拒绝时的处理逻辑。
RejectedExecutionHandler customHandler = new RejectedExecutionHandler() {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
System.out.println("Task rejected: " + r.toString());
// 自定义处理逻辑
}
};
ExecutorService customThreadPoolWithHandler = new ThreadPoolExecutor(
2,
4,
60L,
TimeUnit.SECONDS,
new ArrayBlockingQueue<>(2),
customHandler);
customThreadPoolWithHandler.submit(() -> {
// 任务逻辑
});
customThreadPoolWithHandler.shutdown();
4. ForkJoinPool
ForkJoinPool
是专为任务分解和合并设计的高级线程池,适用于并行计算任务。
ForkJoinPool forkJoinPool = new ForkJoinPool();
ForkJoinTask<?> task = forkJoinPool.submit(() -> {
// 分解和合并任务
});
task.join(); // 等待任务完成
forkJoinPool.shutdown();
5. CompletableFuture
CompletableFuture
提供了异步任务的更高层次抽象,并支持链式处理和组合。
CompletableFuture.supplyAsync(() -> {
// 异步任务
return "Result";
}).thenApply(result -> {
// 下一步处理
return result.toUpperCase();
}).thenAccept(System.out::println);
小结
- Executors 工具类:提供便捷的固定大小线程池、缓存线程池、单线程池和调度线程池的创建方法,适用于大多数常见应用场景。
- ThreadPoolExecutor:提供高度灵活的线程池配置选项,适用于需要精细控制线程池行为的场景。
- 自定义线程池:通过实现
ThreadFactory
和RejectedExecutionHandler
接口,可以创建具有特定行为和属性的线程池。 - ForkJoinPool:适用于需要将任务分解为更小子任务并行执行的场景。
- CompletableFuture:提供流式 API 和组合功能用于异步任务处理,非常适合复杂的异步编程。
选择适合的线程池实现和管理方式可以有效提升多线程应用的性能和可维护性。