线程池的执行流程

合理使用线程池能够带来3个好处:

1)降低资源消耗;2)提高响应速度;3)提高线程的可管理性。

那么线程池是如何工作的呢,借用并发编程艺术一书中的话来描述当一个任务提交给线程池之后,线程池会怎么做?

首先,线程池会判断核心线程池里的线程(线程总数是30,则coreSize有可能是10)是否都在执行任务。如果没有比方说当前只有9个线程在工作,则从核心线程池中创建一个新的线程来执行任务。如果当前已经有10个线程在工作了,则进入下一步;

其次,线程池会判断工作队列是否已经满了,如果工作队列没有满,则将新提交的任务存储在这个工作队列里,如果工作队列已经满了,则进入下一个流程;

最后,线程池判断全部线程是否都在工作,如果没有,即30个线程只有25个在工作,则创建一个新的工作线程来执行任务,如果已经有30个线程来执行,没有任何空闲线程,

则交给饱和策略来处理这个任务(默认的饱和策略为抛异常)。

下面我们借用书中的图来说明:

从图种可以看出,提交任务之后,首先会尝试着交给核心线程池中的线程来执行,但是必定核心线程池中的线程数有限,所以必须要由任务队列来做一个缓存,先将任务放队列中缓存,然后等待线程去执行,最后,由于任务太多,队列也满了,这个时候线程池中剩下的线程就会启动来帮助核心线程池执行任务。如果还是没有办法正常处理新到的任务,则线程池只能将新提交的任务交给饱和策略来处理了。

线程池的创建new ThreadPoolExecutor(corePoolSize,maximumPoolSize,keepAliveTime,milliseconds,

runnableTaskQueue,handler);

其中最后一个参数handler就是饱和策略,java线程池框架提供的4种可策略:

1)AbortPolicy:直接抛出异常

2)CallerRunsPolicy:只用调用者所在线程来运行任务

3)DiscardOldestPolicy:丢弃队列中最近的一个任务,并执行当前任务。

4)DiscardPolicy:不处理,丢弃掉。

最后我们列举一个线程池max=5,core=3,任务队列taskQueue=5;采用饱和策略为1)

则我们看看提交任务给此线程池的执行逻辑如下:

1)首先我们提交第一个任务到线程池,此时核心线程数都还没有用,所以会启动核心线程之一来执行任务,记住为了说明这个流程,我们的任务的占用时间都很长,所以短时间内不会结束;

2)接着提交第二个第三个任务到线程池,他们的执行逻辑同第一个任务是一模一样的,线程池会启动核心线程池中剩下的两个线程来执行你新提交的任务。

3)接着又有新的任务提交过来,这个时候线程池发现核心线程池中的线程已经都在工作中,所以会去看任务队列taskQueue是否满了,发现并没有,是空的,所以将这个任务放入任务队列中等待核心线程池中有空闲线程时自己来取任务执行。

4)接着又提交了4个任务到线程池,他们分别判断核心线程是否空闲,不空闲,然后判断任务队列是否已满,不满,则直接将任务放入队列;

5)接着新的任务又来,则在判断核心线程池和任务队列之后,发现任务依然没有办法处理,则会判断是否线程数达到最大,发现没有,则新启动线程来执行任务;

6)接着又来一个任务,执行流程同5);

7)再来一个任务,发现核心线程池在忙,任务队列也满了,线程池中的全部线程也都在工作,没有办法处理他了,所以他找到了饱和策略,因为饱和策略是默认的抛异常,所以线程池会告诉提交任务的线程,已经没有可以用的线程了。

以上就一个核心线程数是3,总线程数是5,任务队列长度为5,默认策略采用抛异常的策略的从最开始到最后线程池满负荷运作的过程。

时间: 2024-10-14 01:59:42

线程池的执行流程的相关文章

Android AsyncTask内部线程池异步执行任务机制简要分析

如下分析针对的API 25的AsyncTask的源码: 使用AsyncTask如果是调用execute方法则是同步执行任务,想要异步执行任务可以直接调用executeOnExecutor方法,多数情况下我们会使用AsyncTask内部静态的线程池, THREAD_POOL_EXECUTOR,这里并不是要分析AsyncTask内部的流程,而是简单介绍下线程池的工作流程.可以看到THREAD_POOL_EXECUTOR的配置如下: new ThreadPoolExecutor( CORE_POOL_

戏(细)说Executor框架线程池任务执行全过程(下)

上一篇文章中通过引入的一个例子介绍了在Executor框架下,提交一个任务的过程,这个过程就像我们老大的老大要找个老大来执行一个任务那样简单.并通过剖析ExecutorService的一种经典实现ThreadPoolExecutor来分析接收任务的主要逻辑,发现ThreadPoolExecutor的工作思路和我们带项目的老大的工作思路完全一致.在本文中我们将继续后面的步骤,着重描述下任务执行的过程和任务执行结果获取的过程.会很容易发现,这个过程我们更加熟悉,因为正是每天我们工作的过程.除了Thr

戏(细)说Executor框架线程池任务执行全过程(上)

一.前言 1.5后引入的Executor框架的最大优点是把任务的提交和执行解耦.要执行任务的人只需把Task描述清楚,然后提交即可.这个Task是怎么被执行的,被谁执行的,什么时候执行的,提交的人就不用关心了.具体点讲,提交一个Callable对象给ExecutorService(如最常用的线程池ThreadPoolExecutor),将得到一个Future对象,调用Future对象的get方法等待执行结果就好了. 经过这样的封装,对于使用者来说,提交任务获取结果的过程大大简化,调用者直接从提交

通俗易懂,各常用线程池的执行 流程图

作者:林冠宏 / 指尖下的幽灵 掘金:https://juejin.im/user/587f0dfe128fe100570ce2d8 博客:http://www.cnblogs.com/linguanh/ GitHub : https://github.com/af913337456/ 有时候花了大把时间去看一些东西却看不懂,是很 " 蓝瘦 " 的,花时间也是投资. 本文适合: 曾了解过线程池却一直模模糊糊的人 了解得差不多却对某些点依然疑惑的 不适合: 完全没看过的,建议你先去看看其

C# -- 使用线程池 ThreadPool 执行多线程任务

1. 使用线程池 1 class Program 2 { 3 static void Main(string[] args) 4 { 5 WaitCallback wc1 = s =>{ 6 Console.WriteLine("线程ID:{0},开始执行", Thread.CurrentThread.ManagedThreadId); 7 Stopwatch stw = new Stopwatch(); 8 stw.Start(); 9 long result = SumNum

C++11消息队列 + Qt线程池 + QRunnable执行任务简单模型

1.模板类queue,包含头文件<queue>中,是一个FIFO队列. queue.push():在队列尾巴增加数据 queue.pop():移除队列头部数据 queue.font():获取队列头部数据的引用... 2.Qt库的线程池,QThreadPool QThreadPool.setMaxThreadCount():设置线程池最大线程数 QThreadPool.start(new QRunnable(..)):开启线程池调用QRunnable 3.QRunnable执行任务 void r

JAVA线程池的工作流程是怎么样的?

1 当一个任务通过submit或者execute方法提交到线程池的时候,如果当前池中线程数(包括闲置线程)小于coolPoolSize,则创建一个线程执行该任务. 2 如果当前池中线程数大于等于coolPoolSize,则将该任务加入到等待队列. 3 如果任务不能入队,说明等待队列已满,若当前池中线程数小于maximumPoolSize,则创建一个临时线程(非核心线程)执行该任务. 4 如果当前池中线程数已经等于maximumPoolSize,此时无法执行该任务,根据拒绝执行策略处理,后面还会详

12.深入线程池_流程和原理

参考博文:http://blog.csdn.net/mark_lq/article/details/50346999 一.线程池的基本类结构 合理利用线程池能够带来三个好处. 1.降低资源消耗.通过重复利用已创建的线程降低线程创建和销毁造成的消耗 2.提高响应速度.当任务到达时,任务可以不需要等到线程创建就能立即执行 3.提高线程的可管理性.线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控 Executor线程池框架最大优点是把

深入浅出 Java Concurrency (34): 线程池 part 7 线程池的实现及原理 (2)[转]

线程池任务执行流程 我们从一个API开始接触Executor是如何处理任务队列的. java.util.concurrent.Executor.execute(Runnable) Executes the given task sometime in the future. The task may execute in a new thread or in an existing pooled thread. If the task cannot be submitted for execut