线程池好处
- 可以减少线程的频繁创建和销毁 , 提高程序的性能
- 任务提交后 , 就可以立刻执行 , 可以减少任务提交后创建线程的等待时间 , 提高响应速度
线程池的创建和使用
- ExecutorService threadPool = Executors.newFixedThreadPool(3) 使用Executors工具类 , 创建一个固定大小的线程池 , 参数3就是指定线程池的大小
- Future<?> submit(Runnable task); 往线程池当中提交任务 , 可以提交实现Runnable接口的类的实例 , 也可以使用匿名内部类 , 或者lambda表达式 , 下面使用lambda表达式
ExecutorService threadPool = Executors.newFixedThreadPool(3);
threadPool.submit(()->{
System.out.println("鲤鱼");
});
自定义线程池
使用Executors.newFixedThreadPool(3)底层调用的是ThreadPoolExecutor的构造方法 , 因此我们可以通过创建该类从而对线程池的参数进行自定义
ThreadPoolExecutor构造方法
public ThreadPoolExecutor(
int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
线程池的参数
在解释线程池参数之前 , 我们需要了解核心线程和临时线程的概念
核心线程 : 该类线程随着线程池的创建而创建 , 随着线程池销毁而销毁 , 因此是长期存活在线程池当中的
临时线程 : 当线程池的任务过多 , 核心线程无法完成时 , 就会创建临时线程 , 当任务执行结束 , 临时线程长时间不被使用 , 超过了最大存活时间 , 就会被回收
- int corePoolSize : 核心线程数量
- int maximumPoolSize : 最大线程数量 = 核心线程数量 + 临时线程数量
- long keepAliveTime : 临时线程最大存活时间
- TimeUnit unit : 临时线程存活时间单位
- BlockingQueue workQueue : 阻塞队列 , 当提交的任务过多 , 就会将任务存储在阻塞队列中 , 等待空闲线程来执行
- ThreadFactory threadFactory : 线程创建方式
- RejectedExecutionHandler handle : 线程拒绝策略
线程池的拒绝策略
- AbortPolicy 拒绝并抛出异常 , RejectedExecutionException
- DiscardPolicy 拒绝任务但不抛出异常
- DiscardOldestPolicy 丢弃队列最前面的任务 , 然后提交被拒绝的任务
- CallRunsPolicy 有提交任务的线程去处理该任务