题目
Java线程池的基本使用与原理
信息
- 类型:问答
- 难度:⭐
考点
线程池创建,任务提交,线程池关闭
快速回答
Java线程池的基本使用步骤如下:
- 使用
Executors.newFixedThreadPool()创建固定大小的线程池 - 通过
execute()方法提交Runnable任务 - 使用
shutdown()优雅关闭线程池
核心参数:线程池大小需根据任务类型和系统资源合理设置(如CPU核心数)。
解析
原理说明
线程池通过复用线程减少创建/销毁开销,核心组件包括:
- 工作队列:存储待执行任务(
LinkedBlockingQueue) - 线程集合:执行任务的线程
- 线程工厂:定制线程创建
- 拒绝策略:处理队列满时的任务
代码示例
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadPoolDemo {
public static void main(String[] args) {
// 1. 创建固定大小为4的线程池
ExecutorService executor = Executors.newFixedThreadPool(4);
// 2. 提交10个任务
for (int i = 0; i < 10; i++) {
final int taskId = i;
executor.execute(() -> {
System.out.println("任务" + taskId + " 由线程 " +
Thread.currentThread().getName() + " 执行");
});
}
// 3. 优雅关闭线程池
executor.shutdown();
}
}最佳实践
- 线程池大小:CPU密集型任务建议设为
CPU核心数+1,IO密集型可更大 - 关闭顺序:先
shutdown()拒绝新任务,再awaitTermination()等待现有任务完成 - 资源释放:用
try-finally确保关闭:ExecutorService executor = Executors.newFixedThreadPool(4); try { // 提交任务... } finally { executor.shutdown(); }
常见错误
- 忘记关闭:导致线程泄漏,JVM无法退出
- 错误关闭:直接调用
shutdownNow()中断运行中任务 - 无界队列:
newFixedThreadPool使用无界队列,可能引发OOM
扩展知识
- 自定义线程池:推荐直接使用
ThreadPoolExecutor构造函数:new ThreadPoolExecutor( corePoolSize, // 核心线程数 maxPoolSize, // 最大线程数 keepAliveTime, // 空闲线程存活时间 TimeUnit.SECONDS, // 时间单位 new ArrayBlockingQueue<>(100) // 有界队列 ); - 任务类型:
execute()提交Runnable,submit()可提交Callable并获取Future