文章目录
知道线程池是什么以及解决什么问题
线程池(Thread Pool)是一种基于池化思想管理线程的工具,用于管理和复用线程的技术。它由一组预先创建的线程组成,这些线程可以在需要时被重复使用来执行多个任务,从而避免了频繁创建和销毁线程的开销。
线程创建是有一定的开销,频繁创建销毁线程的开销会降低系统性能。线程池可以维护多个已创建的线程,一方面避免了处理任务时频繁创建销毁线程开销的代价,另一方面避免了线程无上限创建导致资源浪费及过分调度问题,保证了对系统资源的充分利用。
线程池解决的核心问题就是资源管理的问题。在并发环境下,任意时刻都无法确定有多少任务需要执行,需要多少资源投入使用。由于这些不确定因素在使用多线程时会带来以下若干问题:
- 频繁创建和销毁线程带来较大的开销。
- 使用不当出现无限制地创建线程,不停的系统申请资源,缺少抑制手段,容易引发系统资源耗尽的风险。
- 系统无法合理有效地管理与分配资源,降低系统的稳定性。
那么,使用线程池可以带来有效解决上述可能出现的一系列问题:
- 降低资源消耗:通过池化技术重复利用已创建的线程,降低线程创建和销毁造成的损耗。
- 提高响应速度:任务到达时,无需等待线程创建即可立即执行。
- 提高线程的可管理性:线程是稀缺资源,如果无限制创建,不仅会消耗系统资源,还会因为线程的不合理分布导致资源调度失衡,降低系统的稳定性。使用线程池可以进行统一的分配、调优和监控。
- 提供更多更强大的功能:线程池具备可拓展性,允许开发人员向其中增加更多的功能。比如延时定时线程池ScheduledThreadPoolExecutor,就允许任务延期执行或定期执行。
Java 内置线程池
在Java 异步编程——Java内置线程调度器(Executor 框架)一文中简单介绍了 Executor 框架以及两级调度模型,现在详细介绍 Executor 框架中相关的线程池类。
Executor、ExecutorService、ThreadPoolExecutor、Executors
Java 里面线程池的顶级接口是 Executor,顶层接口 Executor 提供了一种思想:将任务提交和任务执行进行解耦。用户无需关注如何创建线程,如何调度线程来执行任务,用户只需提供Runnable对象,将任务的运行逻辑提交到执行器(Executor)中,由Executor框架完成线程的调配和任务的执行部分。但是严格意义上讲 Executor 并不是一个线程池,而只是一个执行线程的工具。真正的线程池接口是 ExecutorService (一个 ExecutorService 对象代表一个线程池),这个接口里面声明了一系列管理线程和调度的方式,如:submit()、invokeAll()、invokeAny()、shutDown() 和 shutdownNow() 等,返回 Future 对象,以及可跟踪一个或多个异步任务执行状况返回 Future 的方法。而 ThreadPoolExecutor 是Java中最核心的一个线程池实现类,下面主要以 ThreadPoolExecutor 为例对线程池展开详细介绍。Executors 类,提供了一系列工厂方法用于创建线程池,返回的线程池都实现了 ExecutorService 接口。
Java 内置线程池设计结构及执行机制
ThreadPoolExecutor 是Java中最核心的一个线程池实现类,这里介绍 ThreadPoolExecutor 线程池的运行机制,如下图所示:
执行机制(任务调度与线程调度)
- 在创建了线程池后,开始等待请求。
- 当调用 execute() 或 submit() 方法添加一个请求任务时,线程池会做出如下判断:
- 当任务数量少于 corePoolSize 线程池中的常驻核心线程数时,会自动创建 thread 来处理这些任务并加入线程池;
- 当添加任务数大于 corePoolSize 且少于 maximumPoolSize 时,不再创建线程,而是将这些任务放到阻塞队列中,等待被执行;
- 当阻塞队列满了之后,线程池中的线程数没有超过 maximumPoolSize 最大线程数(非核心线程数),则新建一个线程处理任务并加入到线程池中,从而加速处理阻塞队列;
- 当阻塞队列满了之后,且添加任务大于 maximmPoolSize 时,根据饱和策略决定是否容许继续向线程池中添加任务,默认的饱和策略是 AbortPolicy(直接丢弃)。
- 当一个线程完成任务时,它会从队列中取下一个任务来执行。
- 空闲的线程(非核心线程)会在到达 keepAliveTime 时间之后没有被使用的话就被回收(超过核心线程数的线程销毁,核心线程数以内的线程扔回池子待命)。所以线程池的所有任务完成后,线程池最终收缩只保留 corePoolSize 核心线程数的大小。 <