题目
使用线程池执行简单异步任务
信息
- 类型:问答
- 难度:⭐
考点
线程池创建,任务提交,资源管理
快速回答
在Java中创建固定大小线程池并执行任务的步骤:
- 使用
Executors.newFixedThreadPool()创建线程池 - 通过
execute()方法提交Runnable任务 - 使用
shutdown()关闭线程池
示例代码:
ExecutorService executor = Executors.newFixedThreadPool(4);
executor.execute(() -> System.out.println("Task running"));
executor.shutdown();
## 解析
原理说明
线程池通过复用线程减少创建/销毁开销,newFixedThreadPool创建固定数量线程的池,适合稳定负载场景。核心组件:
- 工作队列:存储待执行任务(默认使用无界队列)
- 线程工厂:标准化线程创建
- 拒绝策略:队列满时的处理机制(默认抛出异常)
代码示例
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核心数+1(I/O密集型可增加)
- 资源释放:必须调用
shutdown()避免资源泄漏 - 异常处理:任务内需捕获异常,否则会导致线程退出
- 替代方案:生产环境建议使用
ThreadPoolExecutor自定义参数
常见错误
- 忘记关闭线程池:导致JVM无法退出(线程持续存活)
- 使用无界队列:
newFixedThreadPool默认使用无界队列,可能引发OOM - 错误捕获异常:未在任务内处理异常导致线程终止
- 误用
shutdownNow():会尝试中断运行中任务(应优先用shutdown())
扩展知识
- 其他线程池类型:
newCachedThreadPool:弹性线程池,适合短时异步任务newSingleThreadExecutor:单线程顺序执行ScheduledThreadPool:支持定时/周期性任务
- 任务提交方式:
execute(Runnable):无返回值submit(Callable):返回Future对象获取结果
- 线程池状态:RUNNING, SHUTDOWN, STOP, TIDYING, TERMINATED