- 简介
- 线程池的组成
- 任务队列:任务队列是一个阻塞队列,保存待执行的任务
- 工作者线程:工作者线程主体就是一个循环,循环从队列中接受任务并执行
- 为什么要用线程池
- 降低资源消耗:通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
- 提高响应速度: 当任务到达时,任务可以不需要的等到线程创建就能立即执行。
- 提高线程的可管理性: 线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。
- 常见的线程池
- 基本对象:ThreadPoolExecutor
- 可重用固定线程数的线程池:FixedThreadPool
- 单个worker线程:SingleThreadExecutor
- 会根据需要创建新线程的线程池:CachedThreadPool
- 线程池的创建
- 通过Executors提供的方法创建,不推荐使用,原因就是FixedThreadPool和SingleThreadExecutor底层都是用LinkedBlockingQueue实现的,这个队列最大长度为Integer.MAX_VALUE,显然会导致OOM
- 通过基本类ThreadPoolExecutor 创建
- 七个参数 | 参数 | 意义 | | —- | —- | | corePoolSize | 线程池常驻核心线程数 | | maximumPoolSize | 能够容纳的最大线程数 | | keepAliveTime | 空闲线程存活时间 | | unit | 存活时间单位 | | workQueue | 存放提交但未执行任务的队列 | | threadFactory | 创建线程的工厂类 | | handler | 等待队列满后的拒绝策略 |
- 线程池工作原理
- 如果正在运行的线程数小于corePoolSize,创建核心线程;
- 大于等于corePoolSize,放入等待队列。
- 如果等待队列已满,但正在运行的线程数小于maximumPoolSize,创建非核心线程;
- 大于等于maximumPoolSize,启动拒绝策略。
- 当一个线程无事可做一段时间keepAliveTime后,如果正在运行的线程数大于corePoolSize,则关闭非核心线程

- 拒绝策略
- AbortPolicy:默认的策略,直接抛出RejectedExecutionException异常,阻止系统正常运行
- CallerRunsPolicy:既不会抛出异常,也不会终止任务,而是将任务返回给调用者。
- DiscardOldestPolicy:抛弃队列中等待最久的任务,然后把当前任务加入队列中尝试再次提交任务。
- DiscardPolicy:直接丢弃任务,不做任何处理。
6. 自定义线程池参数选择
- CPU密集型任务:这种任务消耗的主要是 CPU 资源,最大线程数是CPU线程数+1,比 CPU 核心数多出来的一个线程是为了防止线程偶发的缺页中断,或者其它原因导致的任务暂停而带来的影响,一旦任务暂停,CPU 就会处于空闲状态,而在这种情况下多出来的一个线程就可以充分利用 CPU 的空闲时间
- IO密集型任务:这种任务应用系统大部分的时间处理 I/O 交互,CPU资源占用少, 尽量多配点,可以是CPU线程数*2,或者CPU线程数/(1-阻塞系数)
- 线程池中 submit 和 execute 方法有什么区别
- execute(…) 方法,返回类型是 void ,它定义在 Executor 接口中 , 必须实现Runnable接口 。
- submit(…) 方法,可以返回持有计算结果的 Future 对象,它定义在 ExecutorService 接口中,它扩展了 Executor 接口,其它线程池类像 ThreadPoolExecutor 和 ScheduledThreadPoolExecutor 都有这些方法。
- 线程池状态
- RUNNING:线程池处在RUNNING状态时,能够接收新任务,以及对已添加的任务进行处理
- SHUTDOWN:线程池处在SHUTDOWN状态时,不接收新任务,但能处理已添加的任务,调用线程池的shutdown()接口时切换
- STOP:线程池处在STOP状态时,不接收新任务,不处理已添加的任务,并且会中断正在处理的任务,调用线程池的shutdownNow()接口时切换
- TIDYING:当所有的任务已终止,当线程池在SHUTDOWN状态下,阻塞队列为空并且线程池中执行的任务也为空时,就会由 SHUTDOWN -> TIDYING
- TERMINATED:线程池彻底终止,就变成TERMINATED状态,线程池处在TIDYING状态时,执行完terminated()之后,就会由 TIDYING -> TERMINATED。

