线程池TheadPoolExecutor

使用线程池的好处:

1.重用线程池中的线程,避免因为线程的创建和销毁而带来的开销;

2.有效限制线程池的最大并发数,避免大量的线程之间抢占资源而引起的阻塞;

3.能够对线程进行简单管理,提供定时执行以及指定间隔循环执行等功能;

 

ThreadPoolExecutor是线程池的真正实现,它的构造方法提供了一系列的参数来配置线程池。

ThreadPoolExecutor的构造参数解释:

1.corePoolSize:

核心线程数,默认情况下,核心线程会一直在线程池中存活,即使处于闲置状态;如果将TheadPoolExecutor的allowCoreThreadTimeOut属性设置为true,那么闲置的核心线程在等待新任务到来时会有超时策略,这个时间间隔由keepAliveTime所指定,当等待时间超过keepAliveTime所指定的时长后,核心线程会被终止。

2.maximumPoolSize:

线程池所能容纳的最大线程数量,当活动线程数超过此数量,后续任务会被阻塞,即等待;

3.keepAliveTime:

非核心线程闲置时的超时时长,超过该时长,非核心线程会被回收;当allowCoreThreadTimeOut属性设置为true时,keepAliveTime同样作用于核心线程;

4.unit:

用于指定keepAliveTime参数的时间单位,是一个枚举,使用TimeUnit.xxx来指定;

5.workQueue:

线程池中的任务队列,通过线程池的execute方法提交的Runnable对象会存储在这个参数中;

6.thradFactory

线程工厂,为线程池提供创建新线程的功能。

 

TheadPoolExecutor执行任务的流程:

1.如果线程池中的线程数量未达到核心线程的数量,那么会直接启动一个核心线程来执行任务;

2.如果线程池中的线程数量已经达到或者超过核心线程的数量,那么任务会被插入到任务队列中排队,等待闲置的核心线程去执行;

3.如果在步骤2中无法将任务插入任务队列,这往往是由于任务队列已经满了,这个时候如果线程数量未达到线程池规定的最大值,那么会立刻启动一个非核心线程来执行任务;

4.当步骤3中的线程数量已经到达线程池规定的最大值,那么就拒绝执行此任务;ThreadPoolExecutor会调用RejectedExecutionHandler的rejectedExecution方法来通知调用者;

 

关于ThreadPoolExecutor的配置,可看AsyncTask的配置,规格如下:

1.核心线程数等于CPU核心数+1;

2.线程池的最大线程数为CPU核心数的2倍+1;

3.核心线程无超时机制,非核心线程在闲置时的超时时间为1s,即非核心线程超过1秒即被回收;

4.任务队列的容量为128;

 

线程池的分类

这些线程池都是直接或者间接的配置ThreadPoolExecutor得到的;

1.FixedThreadPool

通过Executors.newFixedThreadPool来创建;

它是一种线程数量固定的线程池,这也是Fixed的由来,当线程处于闲置状态时,它们并不会被回收,除非线程池关闭。

当所有的线程都处于活动状态时,新任务会处于等待状态,直到有线程空闲出来,也就是说,当任务过多时,会出现等待执行的情况;

FixedThreadPool只有核心线程并且这些核心线程不会被回收,意味着它可以更快的响应外界的请求

FixedThreadPool核心线程没有超时机制,并且任务队列也没有大小限制,所以就算线程再多,也不会拒绝执行;

2.CacheThreadPool

通过Executors.newCacheThreadPool来创建;

它是一种线程数量不固定的线程池,他只有非核心线程,并且最大线程数为Integer.MAX_VALUE,即任意大;

当线程池中的线程都处于活动状态,即没有闲置线程时,创建一个新线程来执行处理新任务;不然的话,使用闲置线程来处理,这就是cache的由来;

CacheThreadPool中线程都有一个超时机制,超过60s后闲置线程会被回收;

CacheThreadPool中的任务队列是一个空集合,这将导致任何任务都会被立即执行,因此,它适合执行大量的耗时较少的任务

当整个线程池都处于闲置状态时,线程池中的线程都会超时而被终止,此时CacheThreadPool中实际上是没有任何线程的,几乎不占任何系统资源;

3.ScheduledThreadPool

通过Executors.newScheduledThreadPool创建,它用于执行定时任务和具有固定周期的重复任务,这也就是Scheduled的由来;

它的核心线程数量是固定,而非核心线程数是没有限制的,并且当非核心线程被闲置时会立即被回收;

4.SingleThreadExecutor

通过Executors.SingleThreadExecutor创建,它内部只有一个核心线程,这就是single的由来,它确保所有的任务都在同一个线程中按顺序执行

它的任务队列也没有大小限制;

它的意义在于统一所有的外界任务到一个线程中,使得在这些任务之间不需要处理线程同步的问题;

 

总结:

1.线程池的运作流程

一个任务要被执行时,如果有闲置的核心线程,就用核心线程去执行;

如果核心线程都在忙碌,那就把任务加入任务队列,等待闲置的核心线程去执行;

如果任务队列的容量也满了,此时如果有非核心线程的话,就去开启非核心线程去执行,非核心线程运行完后,有可能会被回收;

如果开启的线程数量超过线程池最大值,线程池就会拒绝任务;

2.使用场景分析

如果要执行大量的并发任务,可以使用CacheThreadPool,它有个好处,使用完后就被回收,不怎么占用资源;

如果想定时或者固定周期的执行任务,可以使用ScheduledThreadPool;

如果是顺序执行,不需要处理同步问题,只是新开启个线程去执行任务的话,可以使用SingleThreadPool;

如果想要快速响应外界请求的话,可以使用FixedThreadPool;

其中FixedThreadPool和SingleThreadPool,ScheduledThreadPool可能会需要等待,而CacheThreadPool不需要等待;

转载于:https://my.oschina.net/u/3491256/blog/906162

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值