ThreadPoolExecutor构建线程池及详解

为什么使用线程池?

1,降低资源消耗,通过重复利用已创建的线程降低线程创建和销毁造成的消耗。

2,提高响应速度,当任务到达时,任务可以不需要等到线程创建就能立即执行。

3,提高线程的可管理性,线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。

如何创建线程池?

通过ThreadPoolExecutor来创建一个线程池。

new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, timeUnit, runnableTaskQueue, handler);

corePoolSize - 核心池的大小。

maximumPoolSize - 线程池最大线程数,如果队列中任务已满,并且当前线程个数小于maximumPoolSize,那么会创建新的线程来执行任务。

keepAliveTime - 当前线程数大于corePoolSize,小于maximumPoolSize时,超出corePoolSize的线程称为非核心线程,当非核心线程空闲keepAliveTime后,将会被销毁。

timeUnit - 线程活动保持时间的单位,DAYS,HOURS, MINUTES, MILLISECONDS

runnableTaskQueue - 任务等待队列,排队的策略时先进先出(FIFO),该任务队列需要继承Thread类或者实现Runnable接口。

线程池工作流程?

首先,线程池通过execute()方法执行某个任务(task),线程池收到这个任务后,

  • 如果当前线程池中的线程数 < corePoolSize,无论之前已经创建的线程是否处于空闲状态,线程池会创建一个新的线程运行这个任务
  • 如果当前线程池中的线程数 > = corePoolSize,线程池会把这个任务添加到等待队列(runnableTaskQueue)中。如果某一个线程空闲了,线程池根据规则从等待队列中取出一个任务执行。
  • 如果当前线程池中的线程数 > corePoolSize, 并且等待队列已经满员,无法再加入新的任务,这时,线程池会创建一个非核心线程执行这个任务。
  • 如果当前线程池中的线程数 = maximumPoolSize,新加入的这个任务会导致线程池抛出一个RejectedExecutionException异常,即线程池拒绝接收这个任务。

一旦线程池中某个线程完成了这个任务,它会去等待队列中拿下一个等待任务。

当线程池中的线程数 > corePoolSize,说明当前线程池中有非核心线程。当某个线程处理完线程后,等待keepAliveTime时间后仍然没有新的任务分配给它,这个线程将会被回收。直到线程数 = corePoolSize时,回收停止。

如下图:

CrazyQA
原文地址:https://www.cnblogs.com/wayne-zhang/p/8317004.html