线程池浅析
一、ThreadPoolExecutor
ThreadPoolExecutor 是线程池类。对于线程池,可以通俗的将它理解为"存放一定数量线程的一个线程集合。线程池允许允许同时运行的线程数量就是线程池的容量;当添加的到线程池中的线程超过它的容量时,会有一部分线程阻塞等待。线程池会通过相应的调度策略和拒绝策略,对添加到线程池中的线程进行管理。"
1. workers
workers 是 HashSet 类型,即它是一个 Worker 集合。而一个 Worker 对应一个线程,也就是说线程池通过 workers 包含了"一个线程集合"。当 Worker 对应的线程池启动时,它会执行线程池中的任务;当执行完一个任务后,它会从线程池的阻塞队列中取出一个阻塞的任务来继续运行。
wokers 的作用是,线程池通过它实现了"允许多个线程同时运行"。
2. workQueue
workQueue 是 BlockingQueue 类型,即它是一个阻塞队列。当线程池中的线程数超过它的容量的时候,线程会进入阻塞队列进行阻塞等待。
通过 workQueue,线程池实现了阻塞功能。
3. mainLock
mainLock 是互斥锁,通过 mainLock 实现了对线程池的互斥访问。
4. corePoolSize 和 maximumPoolSize
corePoolSize 是"核心池大小",maximumPoolSize 是"最大池大小"。它们的作用是调整"线程池中实际运行的线程的数量"。
例如,当新任务提交给线程池时(通过 execute 方法)。
-- 如果此时,线程池中运行的线程数量 -- 如果此时,线程池中运行的线程数量> corePoolSize,但是却 如果设置的 corePoolSize 和 maximumPoolSize 相同,则创建了固定大小的线程池。如果将 maximumPoolSize 设置为基本的无界值(如 Integer.MAX_VALUE),则允许池适应任意数量的并发任务。在大多数情况下,核心池大小和最大池大小的值是在创建线程池设置的;但是,也可以使用 setCorePoolSize(int) 和 setMaximumPoolSize(int) 进行动态更改。5. poolSize poolSize 是当前线程池的实际大小,即线程池中任务的数量。6. allowCoreThreadTimeOut 和 keepAliveTime allowCoreThreadTimeOut 表示是否允许"线程在空闲状态时,仍然能够存活";而 keepAliveTime 是当线程池处于空闲状态的时候,超过 keepAliveTime 时间之后,空闲的线程会被终止。7. threadFactory threadFactory 是 ThreadFactory 对象。它是一个线程工厂类,"线程池通过 ThreadFactory 创建线程"。8. handler handler 是 RejectedExecutionHandler 类型。它是"线程池拒绝策略"的句柄,也就是说"当某任务添加到线程池中,而线程池拒绝该任务时,线程池会通过 handler 进行相应的处理"。
综上所说,线程池通过 workers 来管理"线程集合",每个线程在启动后,会执行线程池中的任务;当一个任务执行完后,它会从线程池的阻塞队列中取出任务来继续运行。阻塞队列是管理线程池任务的队列,当添加到线程池中的任务超过线程池的容量时,该任务就会进入阻塞队列进行等待。
二、线程调度
线程有 5 种状态:新建状态,就绪状态,运行状态,阻塞状态,死亡状态。线程池也有 5 种状态;然而,线程池不同于线程,线程池的 5 种状态是:Running, SHUTDOWN, STOP, TIDYING, TERMINATED。
线程池的拒绝策略,是指当任务添加到线程池中被拒绝,而采取的处理措施。
当任务添加到线程池中之所以被拒绝,可能是由于:第一,线程池异常关闭。第二,任务数量超过线程池的最大限制。
线程池共包括 4 种拒绝策略,它们分别是:AbortPolicy, CallerRunsPolicy, DiscardOldestPolicy 和 DiscardPolicy。
评论