线程池及其7大参数与4大拒绝策略详解
在多线程编程中,为了避免频繁地创建和销毁线程带来的开销,提高资源利用率以及更好地管理线程的生命周期,Java提供了线程池的机制。线程池可以通过预先创建一定数量的线程,使用有限的线程资源来处理多个任务,并且可以更好地管理线程的复用、调度和资源控制。本文将详细介绍线程池的概念、常用参数以及常见的拒绝策略。
1. 线程池概述
线程池是一个线程调度器,它通过维护一个线程队列来管理线程的调度。在Java中,线程池的实现是通过java.util.concurrent.ExecutorService接口来完成的。常用的线程池实现类有ThreadPoolExecutor和ScheduledThreadPoolExecutor。
2. 线程池参数
线程池的性能和行为可以通过调整以下7个参数来进行优化和控制:
-
corePoolSize(核心线程数):线程池中所管理的核心线程的数量。当提交一个任务时,如果核心线程数小于corePoolSize,则会创建一个新的线程来处理任务,即使线程池中有空闲的线程。如果核心线程数已满,任务会被放入工作队列。
-
maximumPoolSize(最大线程数):线程池中允许的最大线程数量。当工作队列已满且线程数未达到最大线程数时,会创建新的线程来处理任务。但是,如果达到最大线程数后,仍然有未处理的任务,线程池将根据拒绝策略来进行处理。
-
keepAliveTime(线程空闲时间):当线程数大于核心线程数且工作队列为空时,多余的线程会等待一段时间,超过指定的空闲时间就会被回收。这个参数只会在allowCoreThreadTimeOut设置为true时生效。
-
unit(时间单位):用于指定keepAliveTime参数的时间单位,例如TimeUnit.SECONDS。
-
workQueue(工作队列):用于存放等待执行的任务。常见的工作队列有SynchronousQueue、LinkedBlockingQueue、ArrayBlockingQueue等。
-
hreadFactory(线程工厂):用于创建新线程的线程工厂。
-
handler(拒绝策略):当工作队列和线程池都已满,无法处理新的任务时,拒绝策略定义了线程池如何处理新任务的策略。常见的拒绝策略有AbortPolicy、DiscardPolicy、CallerRunsPolicy和DiscardOldestPolicy。
3. 拒绝策略
在线程池无法处理新任务时,可以根据不同的需求选择适合的拒绝策略:
-
AbortPolicy(默认):直接抛出RejectedExecutionException异常,表示拒绝执行。
-
DiscardPolicy:直接丢弃当前无法处理的任务,不提供任何通知。
-
CallerRunsPolicy:交由调用线程处理该任务。即由提交任务的线程来执行新的任务,相当于主线程自己执行了该任务。
-
DiscardOldestPolicy:丢弃工作队列中最旧的任务,然后尝试重新提交新的任务。