目录
什么是线程池?
线程池是一种利用池化技术思想来实现的线程管理技术。
大部分情况下是存储了几个可直接调用线程的Java对象,没有线程就去生成线程。当我们使用线程的时候,可以不用单独创建线程,直接使用线程池中的线程,免去了线程的创建与销毁的开销。系统频繁的创建、销毁对象是一个很消耗性能的事情。线程池还将任务的执行和线程的创建解耦开来,让线程的管理更加便利。
线程池的主要流程
Java 如何创建线程池?
Java 创建线程池主要是ThreadPoolExecutor类来完成,ThreadPoolExecutor的有许多重载的构造方法,通过参数最多的构造方法来理解创建线程池有哪些需要配置的参数。ThreadPoolExecutor的构造方法为:
ThreadPoolExecutor(int corePoolSize, // 核心线程数
int maximumPoolSize, // 最大线程数
long keepAliveTime, // 非核心线程过期时间
TimeUnit unit, // 非核心线程过期时间单位
BlockingQueue<Runnable> workQueue,// 阻塞(任务)队列
ThreadFactory threadFactory, // 线程工厂
RejectedExecutionHandler handler) // 饱和策略
下面对参数进行说明:
- corePoolSize:表示核心线程池的大小。当提交一个任务时,如果当前核心线程池的线程个数没有达到corePoolSize,则会创建新的线程来执行所提交的任务,即使当前核心线程池有空闲的线程。如果当前核心线程池的线程个数已经达到了corePoolSize,则不再重新创建线程。
- maximumPoolSize:表示线程池能创建线程的最大个数。如果当阻塞队列已满时,并且当前线程池线程个数没有超过maximumPoolSize的话,就会创建新的线程来执行任务。
- keepAliveTime:空闲线程存活时间。如果当前线程池的线程个数已经超过了corePoolSize,并且线程空闲时间超过了keepAliveTime的话,就会将这些空闲线程销毁,这样可以尽可能降低系统资源消耗。
- unit:时间单位。为keepAliveTime指定时间单位。
- workQueue:阻塞队列。用于保存任务的阻塞队列。可以使用ArrayBlockingQueue, LinkedBlockingQueue, SynchronousQueue, PriorityBlockingQueue。
- threadFactory:创建线程的工程类。可以通过指定线程工厂为每个创建出来的线程设置更有意义的名字,如果出现并发问题,也方便查找问题原因。
- handler:饱和策略。当线程池的阻塞队列已满和指定的线程都已经开启,说明当前线程池已经处于饱和状态了,那么就需要采用一种策略来处理这种情况。采用的策略有这几种:
- AbortPolicy: 直接拒绝所提交的任务,并抛出RejectedExecutionException异常;
- CallerRunsPolicy:只用调用者所在的线程来执行任务;
- DiscardPolicy:不处理直接丢弃掉任务;
- DiscardOldestPolicy:丢弃掉阻塞队列中存放时间最久的任务,执行当前任务;
- Policy:自定义操作。
几种常用的线程池
Java,通过 Executors 提供了5种常用线程池,根据业务可快速创建线程池。
1 newSingleThreadPool 单例线程池。核心线程和最大线程为1。并且当前线程停止或者发送异常时,线程池会立即启动一个新的线程,保证线程池中拥有一个可用线程。
2 newFixedThreadPool 定长线程池。核心线程数和最大线程数相同,通过 nThreads 配置。当任务数量大于nThreads的时候,会将该任务放入阻塞队列中,等待线程空闲。
3 newCachedThreadPool 缓存线程池。无核心线程。处理任务时,有空闲线程则使用空闲线程,没有空闲线程则创建一个新线程,并且该线程的空闲等待时间默认为60s。
4 newScheduledThreadPool 定时任务线程池。以一定的时间周期去执行任务。
该线程池它的核心是ScheduledThreadPoolExecutor,但是它继承了ThreadPoolExecutor。
5 newWorkStealingPool 核心设计思想是分而治之,将一个任务拆分成多个小任务,最终结果是将多个小任务的结果合并得到,所以它适合处理耗时并大的任务,比如从1加到10万。它的核心是ForkJoinPool。
线程池的优势:
- 提升系统的响应速度。【不用频繁的创建、销毁对象】
- 降低服务器压力。【可避免线程滥用,造成服务器宕机】
- 方便统一管理池内所有的线程。【可使用线程池 创建和销毁 线程 等】