题目
如何使用线程池执行多个Runnable任务?
信息
- 类型:问答
- 难度:⭐
考点
线程池创建,任务提交,线程池关闭
快速回答
使用线程池执行任务的步骤:
- 通过
Executors.newFixedThreadPool()创建固定大小的线程池 - 使用
execute()方法提交Runnable任务 - 任务执行完成后调用
shutdown()关闭线程池 - 使用
isTerminated()检查线程池是否完全关闭
原理说明
线程池通过复用线程减少创建/销毁开销,提高系统性能。ExecutorService是Java提供的线程池接口,Executors工具类提供创建常用线程池的方法。
代码示例
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class ThreadPoolExample {
public static void main(String[] args) {
// 创建固定大小为3的线程池
ExecutorService executor = Executors.newFixedThreadPool(3);
// 提交5个任务
for (int i = 1; i <= 5; i++) {
final int taskId = i;
executor.execute(() -> {
System.out.println("执行任务" + taskId + ", 线程: " +
Thread.currentThread().getName());
try {
// 模拟任务执行时间
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
// 关闭线程池(不再接受新任务)
executor.shutdown();
try {
// 等待所有任务完成,最多等待10秒
if (!executor.awaitTermination(10, TimeUnit.SECONDS)) {
System.out.println("仍有任务未完成");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("所有任务执行完成");
}
}最佳实践
- 使用
try-with-resources管理线程池(Java 19+) - 通过
awaitTermination()等待任务完成 - 根据任务类型选择线程池大小:CPU密集型任务建议
N+1(N为CPU核心数),I/O密集型任务建议2N
常见错误
- 忘记关闭线程池:导致JVM无法退出
- 错误使用
shutdownNow():会尝试中断正在执行的任务 - 不合理设置线程池大小:过大导致资源竞争,过小导致任务堆积
- 任务中未处理异常:导致工作线程异常终止
扩展知识
ThreadPoolExecutor:可自定义核心参数(核心线程数、最大线程数、存活时间等)ScheduledThreadPoolExecutor:支持定时/周期性任务- 工作队列:
LinkedBlockingQueue(默认无界队列),SynchronousQueue(直接传递队列) - 拒绝策略:当任务超出处理能力时的处理机制(如抛出异常、丢弃任务等)