专注Java教育14年 全国咨询/投诉热线:400-8080-105
动力节点LOGO图
始于2009,口口相传的Java黄埔军校
首页 hot资讯 线程池工作流程详解

线程池工作流程详解

更新时间:2020-11-16 17:36:42 来源:动力节点 浏览3259次

线程是一种宝贵的资源,也是一种有限的资源,创建和销毁线程需要付出不菲的代价。这时候就要用到线程池了,线程池维护着多个线程,等待着监督管理者分配可并发执行的任务。这避免了在处理短时间任务时创建与销毁线程的代价。本文我们就一起来深入学习线程池工作流程

线程池工作流程可以拆分成以下几个部分:

1.提交任务

当向线程池提交一个新的任务时,线程池有三种处理情况,分别是:创建一个工作线程来执行该任务、将任务加入阻塞队列、拒绝该任务。提交任务的过程也可以拆分成以下几个部分:当工作线程数小于核心线程数时,直接创建新的核心工作线程当工作线程数不小于核心线程数时,就需要尝试将任务添加到阻塞队列中去如果能够加入成功,说明队列还没有满,那么需要做以下的二次验证来保证添加进去的任务能够成功被执行验证当前线程池的运行状态,如果是非RUNNING状态,则需要将任务从阻塞队列中移除,然后拒绝该任务验证当前线程池中的工作线程的个数,如果为0,则需要主动添加一个空工作线程来执行刚刚添加到阻塞队列中的任务如果加入失败,则说明队列已经满了,那么这时就需要创建新的“临时”工作线程来执行任务如果创建成功,则直接执行该任务如果创建失败,则说明工作线程数已经等于最大线程数了,则只能拒绝该任务了。

2.创建工作线程

创建工作线程需要做一系列的判断,需要确保当前线程池可以创建新的线程之后,才能创建。首先,当线程池的状态是 SHUTDOWN 或者 STOP 时,则不能创建新的线程。另外,当线程工厂创建线程失败时,也不能创建新的线程。还有就是当前工作线程的数量与核心线程数、最大线程数进行比较,如果前者大于后者的话,也不允许创建。除此之外,会尝试通过 CAS 来自增工作线程的个数,如果自增成功了,则会创建新的工作线程,即 Worker 对象。然后加锁进行二次验证是否能够创建工作线程,最后如果创建成功,则会启动该工作线程。

3.启动工作线程

当工作线程创建成功后,也就是 Worker 对象已经创建好了,这时就需要启动该工作线程,让线程开始干活了,Worker 对象中关联着一个 Thread,所以要启动工作线程的话,只要通过 worker.thread.start() 来启动该线程即可。启动完了之后,就会执行 Worker 对象的 run 方法,因为 Worker 实现了 Runnable 接口,所以本质上 Worker 也是一个线程。通过线程 start 开启之后就会调用到 Runnable 的 run 方法,在 worker 对象的 run 方法中,调用了 runWorker(this) 方法,也就是把当前对象传递给了 runWorker 方法,让他来执行。

4.获取任务并执行

在 runWorker 方法被调用之后,就是执行具体的任务了,首先需要拿到一个可以执行的任务,而 Worker 对象中默认绑定了一个任务,如果该任务不为空的话,那么就是直接执行。执行完了之后,就会去阻塞队列中获取任务来执行,而获取任务的过程,需要考虑当前工作线程的个数。如果工作线程数大于核心线程数,那么就需要通过 poll 来获取,因为这时需要对闲置的线程进行回收;如果工作线程数小于等于核心线程数,那么就可以通过 take 来获取了,因此这时所有的线程都是核心线程,不需要进行回收,前提是没有设置 allowCoreThreadTimeOut。

以上就是整个线程池工作流程,我们对每个线程池工作步骤都进行了详细的讲解,为了加深对线程池的理解可以观看本的多线程教程,深入学习更多的还没有掌握的线程池知识。

提交申请后,顾问老师会电话与您沟通安排学习

免费课程推荐 >>
技术文档推荐 >>