ThreadPoolExecutor线程池?

Posted

tags:

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

当我们需要实现并发、异步等操作时,可以使用ThreadPoolExecutor。

ThreadPoolExecutor

线程池:

系统中,我们创建(extend Thread/implement Runnable)、销毁(正常run方法完成后线程终止)线程的代价是比较高昂的。
如果频繁地创建和销毁进程,会大大降低系统运行效率和吞吐量。
线程池使得线程可以被复用,避免了线程频繁创建和销毁的开销,提高系统的运行效率和吞吐量。

实例

ThreadPoolExecutor.execute(new Runnable () );

相关概念:

Task任务:new Runnable ()
任务就是一个Runnable的对象,任务的执行方法就是该对象的run方法。

缓冲队列:workQueue

一个阻塞队列。

BlockingQueue<Runnable> workQueue;

corePoolSize:核心线程数
核心线程会一直存活,即使没有任务需要执行。
当线程数小于核心线程数时(还未满,就会一直增),即使有线程空闲,线程池也会优先创建新线程处理。

maxPoolSize:最大线程数
当线程数大于corePoolSize,且任务队列已满时。线程池会创建新线程来处理任务,直到线程数量达到maxPoolSize。

execute(Runnable)

通过execute将一个任务交由线程池管理。

当一个任务通过execute方法欲添加到线程池时,线程池采用的策略如下(即添加任务的策略):

1、如果此时线程池中的数量小于corePoolSize,即使线程池中的线程都处于空闲状态,也要创建新的线程来处理被添加的任务。

2、如果此时线程池中的数量等于corePoolSize,但是缓冲队列workQueue未满,那么任务被放入缓冲队列。

3、如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量小于maximumPoolSize,建新的线程来处理被添加的任务。

4、如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量等于maximumPoolSize,那么通过handler所指定的策略来处理此任务。

如下图:

希望对您有所帮助!~

参考技术A 四种线程池:
FixedThreadPool:固定数量的线程池,核心线程数和最大线程数相同,使用链表阻塞队列
CachedThreadPool:缓存线程池,核心线程数为0,最大线程数为Integer.MAX_VALUE,非核心线程等待时间为60s,使用SynchronousQueue队列
SingleThreadPool:单例,核心和最大都是1,使用链表阻塞队列LinkedBlockingQueue。
ScheduledThreadPool: 定时延时执行,使用DelayedWorkQueue本回答被提问者和网友采纳

线程池源码分析之ThreadPoolExecutor

前言

今天老吕给大家来分享下ThreadPoolExecutor 线程池的实现逻辑,大家伙认真看,一般人我不告诉他的。

线程池相关类图      

JDK中线程池相关的类结构关系图

获取不同特性的线程池

在Executors中可以获取到如下类型的线程池:

//下面这几种线程池的实现基础都是ThreadPoolExecutor 线程池实现类static ExecutorService executorService1 = Executors.newFixedThreadPool(10);static ExecutorService executorService2 = Executors.newCachedThreadPool();static ExecutorService executorService3 = Executors.newSingleThreadExecutor();static ExecutorService executorService4 = Executors.newScheduledThreadPool(10);static ExecutorService executorService5 = Executors.newSingleThreadScheduledExecutor();//它的实现比较特殊用的ForkJoinPool 线程池实现类static ExecutorService executorService6 = Executors.newWorkStealingPool();

ThreadPoolExecutor的实现逻辑

上面6种类型的线程池,大部分是以ThreadPoolExecutor为基础来实现的,我们今天只分析 ThreadPoolExecutor的实现逻辑。

 首先看下著名的7大参数

public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)

这是我总结的7大参数的含义,很简单是吧

下面看下线程池线程数量扩张与任务队列的关系,仔细体会

在源码中Worker本质上就是一个Thread,只有第一个任务(firstTask)是通过构造函数传进去的,之后执行的任务都是通过任务队列获取,从而也可以看出任务的本质是实现了Runnable接口的消息而已。

最后总结下这个线程池的实现逻辑

1、一个任务过来后,除了 新增一个线程时会将任务直接送到新线程里面

2、其它情况下所有的任务都是先放入任务队列

3、线程池中的所有线程一视同仁都是从任务队列中获取任务

4、假如你的最大线程个数为100,任务队列容量为很小,比如:容量为10,在并发较高场景下就会出现 池中线程 空闲线程很多,但是客户端收到 拒绝执行的奇怪现象。如果你理解了前3点,这个现象的原因你也就知道了。

5、谢谢大家,今天就到这里,有疑问加作者微信,进群探讨。



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

线程详解之线程池ThreadPoolExecutor

java线程池源码的简单分析

公司发的小师妹问我java中的线程池,这么讲可还行?

公司发的小师妹问我java中的线程池,这么讲可还行?

公司发的小师妹问我java中的线程池,这么讲可还行?

java~线程池的总结~续