线程池是一种多线程处理形式,它是预先创建并维护一定数量的线程,这些线程在需要时可以被复用而不是每次创建新线程。线程池在执行异步任务、处理并发请求或执行批处理作业时尤其有用,因为它可以减少创建和销毁线程的开销,改善系统性能和资源利用率,并且能够更好地控制系统资源和执行策略。
在Java中,线程池是通过java.util.concurrent
包中的ThreadPoolExecutor
类实现的,它具备以下主要特点和工作流程:
- 线程池配置:
- 核心线程数(corePoolSize):线程池中即使没有任务执行也会保有的线程数。
- 最大线程数(maximumPoolSize):线程池能容纳的最大线程数,超出此数目的任务将被拒绝或等待。
- 阻塞队列(work queue):用于存储等待执行的任务,常用的队列类型有无界队列(如
LinkedBlockingQueue
)和有界队列(如ArrayBlockingQueue
)。 - 空闲线程存活时间(keepAliveTime):非核心线程在空闲时等待新任务的时间,超过这个时间则会被回收。
- 拒绝策略(RejectedExecutionHandler):当线程池饱和,既没有可用线程也无法将任务放入队列时,采用的拒绝策略,如直接丢弃、抛出异常、由调用者线程执行等。
- 任务提交与执行:
- 应用程序通过
execute()
或submit()
方法将Runnable
或Callable
对象提交给线程池。 - 线程池根据当前线程数和队列情况,创建新的线程或者将任务放入队列中。
- 当线程执行完一个任务后,会从队列中取出下一个任务执行,如果队列为空且线程数超过核心线程数,则可能回收线程。
- 线程池生命周期管理:
- 线程池可以根据预设策略调整线程数量,保持合适的线程活跃度。
- 当调用
shutdown()
方法时,线程池不再接受新任务,等待现有任务执行完毕后关闭。 - 调用
shutdownNow()
方法会尝试取消所有正在执行的任务并立即关闭线程池。
线程池的工作流程如下图所示:
通过合理的配置和使用线程池,可以优化程序性能,防止系统资源过度消耗,同时简化并发编程模型。线程池广泛应用于服务器端并发处理、定时任务调度等多个领域。