JDK线程池原理剖析

Posted tspeking

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JDK线程池原理剖析相关的知识,希望对你有一定的参考价值。

这篇文章不打算讲解什么是线程池?线程池怎么用?直接讲解原理

1、线程池关键参数解释
JDK 线程池的实现类是 ThreadPoolExecutor,构造函数关键参数解释如下:
corePoolSize 核心线程,线程池维持的线程数量,即使没有任务执行也会维持这个数量不变,除非设置了 allowCoreThreadTimeOut 这个参数为 true
maximumPoolSize 线程池中允许创建线程的最大数量
keepAliveTime 非核心线程的空闲等待时间,超过这个时间将被销毁
unit 针对keepAliveTime 参数的时间单位
workQueue 任务队列
 
2、 execute和submit的区别?
1)submit有返回值
2)submit提交的线程类型,会被jdk包装成一个FutureTask
 
3、运行原理
3.1任务执行流程
这不是一个流程图,是为了说明线程启动到执行任务的大概流程
技术分享图片
 
3.2 源码分析
先说下执行主流程,再细看源码。
执行流程:execute(Runnable command) >>addWorker(Runnable firstTask, boolean core)>>runWorker(Worker w)
源码分析:
1)execute(Runnable command)方法
技术分享图片
  该方法会调用addWorker(Runnable firstTask, boolean core)方法执行任务
2)addWorker(Runnable firstTask, boolean core) 方法
该方法代码比较长,我们看下关键的代码部分
技术分享图片
技术分享图片
既然启动线程了,那我们就去Worker里看看
3) Worker 内部类
技术分享图片
既然2)中调用了start()方法,那么必然会调用Worker的 run()方法
技术分享图片
接下来看 runWorker(this)方法,最最关键的部分就在这里,老办法,我们也还是看最关键的代码片段
技术分享图片
4)看下这个方法 processWorkerExit(Worker w, boolean completedAbruptly)
技术分享图片
            总结一下,线程池就是维护一个线程集合,用这些线程来反复的执行任务,这些线程分为核心线程和非核心线程,核心线程一般不会被销毁,就算是没有任务也会空闲等待(除了设置 allowCoreThreadTimeOut参数),非核心线程,当空闲等待时间到达设置的参数范围,就会被销毁回收。比较难理解的是JDK是如何维护线程集合并执行任务?这里在说一下,线程池初始化,当第一个任务来的时候,线程池会创建一个线程并将该线程存入一个线程集合,刚才的任务作为该线程的第一个任务执行,执行完该任务,此时线程不会立即结束,会通过getTask()方法,以阻塞等待方式从任务队列里面获取任务执行,因此如果阻塞队列有任务,就取出任务执行,如果队列没有任务,就阻塞等待任务,所以正常情况下,该线程会一直存活。当第二个任务来了以后,会执行和第一个任务同样的动作,以此类推,直到核心线程数量达到corePoolSize设置的参数数量,这样就形成了线程集合,也就是线程池。当任务很多的时候,核心线程不能及时全部处理完毕,此时线程池就会将任务存入任务队列,如果队列满了,并且 maximumPoolSize 大于 corePoolSize,就会创建非核心线程执行任务。

以上是关于JDK线程池原理剖析的主要内容,如果未能解决你的问题,请参考以下文章

二期 0005 线程池原理剖析&锁的深度化

线程池原理剖析

线程池核心原理剖析

高效开发:线程池的使用和基本原理剖析

线程池原理剖析

线程池的探索(下)