1、 处理流程
(1) 如果当前运行的线程数少于corePoolSize,则创建新线程来执行任务。
(2) 如果运行线程数不少于corePoolSize,则将任务加入BlockingQueue。
(3) 如果BlockingQueue队列已满,则创建新线程来执行任务。
(4) 如果创建新线程会使线程总数超出maximumPoolSize,任务将被拒绝。
2、 工作线程:
线程池创建线程时,会将线程封装成工作线程Worker,Worker执行完任务之后还会循环获取工作队列中的任务来执行。
3、 线程池中的线程执行任务分为两种情况,如下。
(1) 在execute(Runnable command)方法中创建一个线程时,会让这个线程执行当前任务。
(2) 这个线程执行完当前任务后,会反复从BlockingQueue获取任务来执行。
调用线程池的prestartAllCoreThread()方法可以提前创建并启动所有基本线程。
4、 创建线程池:
(1) corePoolSize:线程池基本线程数
(2) workQueue:任务队列,FIFO先进先出。
(3) maximumPoolSize:线程池最大数量,如果线程数多于corePoolSize并且workQueue已满,则会创建新线程,但总数不会超过maximumPoolSize。
(4) ThreadFactory:用于自定义创建线程,方便给线程起名字。
(5) RejectedExecutionHandler:饱和策略,当队列和线程池都满了,说明线程池处于饱和状态,则必须要采取一种策略来处理新提交的任务。
有如下四种:
①AbortPolicy:直接抛出异常
②CallerRunsPolicy:只用调用者所在线程来运行任务。
③DiscardOldestPolicy:丢弃队列中最近的一个任务,并执行当前任务。
④DiscardPolicy:不处理,丢弃掉。
也可以自定义策略,如记录日志或者持久化任务。
(6) keepAliveTime:线程活动保持时间,线程池的工作线程空闲后,保持存活的时间。TimeUnit:线程活动保持时间的单位。
5、 向线程池提交任务:
(1) execute()方法提交任务没有返回值
(2) submit()方法会返回一个future类型的对象
6、 关闭线程池
(1) shutdown方法会等当前任务执行完毕
(2) shutdownNow方法会中断正在执行任务的线程