栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

线程池源码分析

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

线程池源码分析

  • 1.为什么要使用线程池
  • 2.线程池相关类继承结构
  • 3.ThreadPoolExecutor实现
    • 3.1submit和execute方法实现
    • 3.2execute代码执行流程
    • 3.3Worker类
  • 4.shutdown和shutdownNow的区别

1.为什么要使用线程池

       假如没有线程池,当存在较多的并发任务的时候,每执行一次任务,系统就要创建一个线程,任务完成后进行销毁,一旦并发任务过多,频繁的创建和销毁线程将会大大降低系统的效率。线程池能够对线程进行统一的分配,通过固定数量的线程来负责处理任务,避免了频繁的创建和销毁对象,使线程能够重复的利用,执行多个任务。

2.线程池相关类继承结构

Executor 最顶层接口,仅有execute方法。真正的线程池接口应该是它的子接口ExecutorService
ExecutorService接口,主要对Executor接口补充了一些方法,例如shutdown()、submit()等方法
ThreadPoolExecutor ExecutorService的默认实现,作为自定义线程池的主要类。
ScheduledExecutorService 用来解决任务重复执行的问题
ScheduledThreadPoolExecutor 继承ThreadPoolExecutor的ScheduledExecutorService接口实现,周期性任务调度的类实现。

3.ThreadPoolExecutor实现

corePoolSize
线程池中保存的线程个数,包含了空闲线程
maximumPoolSize
为线程池中最多允许线程个数
keepAliveTime
当线程产生的数量多于core时候,空闲线程在这个时间如果没有新任务将被终止
unit
keepAliveTime的时间单位,可直接使用TimeUnit枚举类
workQueue
线程工作任务队列。任务被执行前保存至工作队列 常用的有ArrayBlockingQueue、linkedBlockingQuene、priorityBlockingQuene等等
threadFactory
执行程序创建新线程时使用的工厂,默认为DefaultThreadFactory
handler
由于超出线程范围和队列容量而使执行被阻塞时所使用的处理程序,主要有四种AbortPolicy、CallerRunsPolicy、DiscardOldestPolicy、DiscardPolicy

3.1submit和execute方法实现

submit和execute都可以向线程池提交任务,不同的是,submit可以拿到执行的结果,execute则不行。

submit方法

execute方法

从源码中可以看出submit底层调用的也是execute,只不过是对结果进行了封装,核心逻辑还是在execute方法里,因此我们以分析execute为重点。

3.2execute代码执行流程

3.3addWorker方法

 Expand source

3.3Worker类

从源码中可以看出Worker继承了AbstractQueuedSynchronizer,实现了独占非重入锁的功能,Worker有两个重要的属性,一个是thread工作线程,一个是firstTask待执行的任务。

Worker类里面的核心方法是runWorker,具体代码如下

接下来看getTask()方法

图中标红的两个部分结合在一起,实现了,线程池的这个特性,当线程产生的数量多于core时候,空闲线程在这个时间如果没有新任务将被终止。

4.shutdown和shutdownNow的区别

shutdown源码

shutdownNow

从源码中可以看出来,shutdown和shutdownNow的主要区别在interruptIdleWorkers和interruptWorkers这两个方法上。接下来看这两个方法的实现。

interruptIdleWorkers源码如下

interruptWorkers源码如下

可以看到interruptWorkers方法最终调用了Worker类的interruptIfStarted方法,interruptIfStarted方法如下

从源码中可以看出,shutdown在关闭线程池的时候会调用资源的tryLock方法尝试获取锁,在线程还有任务执行的时候,tryLock获取锁失败,在线程执行完释放锁之后,tryLock就可以获取锁成功,从而达到,只有在线程执行完任务之后才关闭线程池的目的。而shutdowNow则不关心是否可以获取锁,只要线程状态正确,就会打断线程的执行,关闭线程。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/338228.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号