前言
笔者最近刚刚换了工作。发现年纪大了。记性就是不好。很多细节都记不住。俗话说好记性不如烂笔头。准备将线程池系列好好整理一下。一方面方便自己平时的翻阅。一方面也和大家一起进步。
内卷的厉害该学还是学!
系列文章
- 线程池系列 – (1)背景介绍
- 线程池系列 – (2)线程池的状态
- 线程池系列 – (3)拒绝策略
- 线程池系列 – (4)工作流程
- 线程池系列 – (5)shutdown && shutdownNow
- 线程池系列 – (6)submit
线程池产生的背景
一个事物的出现,必然是为了解决某一个问题。线程池也不例外。想一些。如果没有使用线程池。当在Android开发中需要做异步操作的时候去new Thread()
.当非常多任务需要创建的时候,势必会造成很大的资源开销。而且多个线程。其管理上面也非常的繁琐。
线程池的出现可以有效的处理这种多线程所带来的一系列问题。
非常推荐美团的 Java线程池实现原理及其在美团业务中的实践,算是我看过对线程池说的比较详细的文章。
线程池的优点
线程池正是使用了 池化
的思想,将没有约束管理的线程做到统一的管理,依然引用 Java线程池实现原理及其在美团业务中的实践中总结的几个优点。
-
降低资源消耗
:通过池化技术重复利用已创建的线程,降低线程创建和销毁造成的损耗。 -
提高响应速度
:任务到达时,无需等待线程创建即可立即执行。 -
提高线程的可管理性
:线程是稀缺资源,如果无限制创建,不仅会消耗系统资源,还会因为线程的不合理分布导致资源调度失衡,降低系统的稳定性。使用线程池可以进行统一的分配、调优和监控。 -
提供更多更强大的功能
:线程池具备可拓展性,允许开发人员向其中增加更多的功能。比如延时定时线程池ScheduledThreadPoolExecutor,就允许任务延期执行或定期执行。
创建线程池
Java 本身就提供了一个可以快速创建线程池的类 Executors
,看一下其对应的创建线程池的方法。
其内部都是创建了一个 ThreadPoolExecutor
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
复制代码
我们可以依据自己的需要自定义一个线程池。例如在 okhttp
中就定了一个线程池
okhttp 3.14.9
Java
版本
public synchronized ExecutorService executorService() {
if (executorService == null) {
executorService = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS,
new SynchronousQueue<>(), Util.threadFactory("OkHttp Dispatcher", false));
}
return executorService;
}
复制代码
okhttp 4.9.0
kotlin
版本
@get:Synchronized
@get:JvmName("executorService") val executorService: ExecutorService
get() {
if (executorServiceOrNull == null) {
executorServiceOrNull = ThreadPoolExecutor(0, Int.MAX_VALUE, 60, TimeUnit.SECONDS,
SynchronousQueue(), threadFactory("$okHttpName Dispatcher", false))
}
return executorServiceOrNull!!
}
复制代码
参数介绍
corePoolSize
核心线程数
maximumPoolSize
表示最大线程数量。
keepAliveTime
和unit
共同确定了一个时间。代表着线程多久没有执行任务执行。线程就会被回收。
workQueue
是线程任务的阻塞队列。这个在后面会详细介绍。
threadFactory
线程创建工厂
handler
线程池的拒绝策略
详细的作用可以在系列文章中查看