一、线程池的五种创建方式
Executors目前提供了五种不同的线程池创建:
类型 |
描述 |
new CachedThreadPool() |
它是一种用来处理大量短时间工作任务的线程池,具有几个鲜明特点:它会试图缓存线程并重用,当无缓存线程可用时,就会创建新的工作线程;如果线程闲置的时间超过60秒,则被终止并移出缓存;长时间闲置时,这种线程池并不会消耗什么资源,其内部使用SynchronousQueue作为工作队列; |
new FixedThreadPool() |
创建固定大小的线程池,背后使用的是无界的工作队列,任何时候最多有nThreads个工作线程是活动的。这意味着,如果任务数量超过了活动队列数目,将在工作队列中等待空闲线程出现;如果有工作线程退出,将会有新的工作线程被创建,以补足指定的数目n Threads。 |
new SingleThreadExcuteor() |
它的特点在于工作线程数目被限制为1,操作一个无界的工作队列,所以保证了所有任务都是被顺序执行的,最多只会有一个任务处于活动状态,并且不允许使用者改动线程池实例,因此可以避免其改变线程数目。 |
newSingleThreadScheduledExcutor()和newScheduleThreadPool(int corePoolSize) |
创建的是个ScheduledExcutorService,可以进行定时或周期性的工作调度,区别在于单一工作线程还是多个工作线程。 |
newWorkStealingPool(int parallelism) |
这是一个经常被人忽略的线程池,Java 8才加入这个创建方法,其内部会构建ForkJoinPool,利用Work-Stealing算法,并行地处理任务,不保证处理顺序。 |
二、线程池的几种参数及其含义
参数名 |
含义 |
corePoolSize |
核心线程数,核心线程会一直存活,即使没有任务需要处理。当线程数小于核心线程数时,即使现有的线程空闲,线程池也会优先创建新线程来处理任务,而不是直接交给现有的线程处理;核心线程在allowCoreThreadTimeout被设置为true时会超时退出,默认情况下不会退出。 |
maxPoolSize |
当线程数大于或等于核心线程,且任务队列已满时,线程池会创建新的线程,直到线程数量达到maxPoolSize。如果线程数等于最大线程数,则已经超出线程池的处理能力,线程池会拒绝处理任务而抛出异常。 |
keepAliveTime |
当线程空闲时间达到keepAliveTime,该线程会退出,直到线程数量达到corePoolSize。如果allowCoreThreadTimeout被设置为true,则所有线程均会退出直到线程数量为0. |
allowCoreThreadTimeout |
是否允许核心线程空闲退出。 |
queueCapacity |
任务队列容量。从maxPoolSize的描述上可以看出,任务队列的容量会影响到线程的变化,因此任务队列的长度也需要恰当的设置。 |
RejectedExcutionHandler |
饱和策略。当队列和线程池都满了,说明线程池处于饱和状态,那么必须对新提交的任务采用一种特殊的策略来进行处理。这个策略默认配置是AbortPolicy,表示无法处理新的任务而抛出异常。JAVA提供了4中策略: |