JAVA线程池ThreadPoolExecutor

线程池概念:

线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。

常用线程池

1. 最常用构造方法为:

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

2. Java 线程池类别

Java通过Executors提供五种线程池,分别为:
newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序

newWorkStealingPool   获取当前可用的线程数量进行创建作为并行级别

(FIFO, LIFO, 优先级)执行

// 固定工作线程数量的线程池  
ExecutorService executorService1 = Executors.newFixedThreadPool(3);  
  
// 一个可缓存的线程池  
ExecutorService executorService2 = Executors.newCachedThreadPool();  
  
// 单线程化的Executor  
ExecutorService executorService3 = Executors.newSingleThreadExecutor();  
  
// 支持定时的以及周期性的任务执行  
ExecutorService executorService4 = Executors.newScheduledThreadPool(3);  

3. 参数详细说明

 corePoolSize: 线程池维护线程的最少数量

 maximumPoolSize:线程池维护线程的最大数量

 keepAliveTime: 线程池维护线程所允许的空闲时间

unit: 线程池维护线程所允许的空闲时间的单位

workQueue: 线程池所使用的缓冲队列

handler: 线程池对拒绝任务的处理策略

 当一个任务通过execute(Runnable)方法欲添加到线程池时

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

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

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

   4.  如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量等于maximumPoolSize,那么通  过 handler所指定的策略来处理此任务。也就是:处理任务的优先级为:核心线程corePoolSize、任务队列workQueue、最大线 程maximumPoolSize,如果三者都满了,使用handler处理被拒绝的任务。  

当线程池中的线程数量大于 corePoolSize时,如果某线程空闲时间超过keepAliveTime,线程将被终止。这样,线程池可以动态的调整池中的线程数

5. handler有四个选择      

  • java.util.concurrent.ThreadPoolExecutor.AbortPolicy 这个是默认使用的拒绝策略,如果有要执行的任务队列已满,且还有任务提交,则直接抛出异常信息

  • java.util.concurrent.ThreadPoolExecutor.DiscardPolicy 这个是忽略策略,如果有要执行的任务队列已满,且还有任务提交,则直接忽略掉这个任务,即不抛出异常也不做任何处理.

  • java.util.concurrent.ThreadPoolExecutor.DiscardOldestPolicy 忽略最早提交的任务.如果有要执行的任务队列已满,此时若还有任务提交且线程池还没有停止,则把队列中最早提交的任务抛弃掉,然后把当前任务加入队列中.

  • java.util.concurrent.ThreadPoolExecutor.CallerRunsPolicy 这个是来着不拒策略.如果有要执行的任务队列已满,此时若还有任务提交且线程池还没有停止,则直接运行任务的run方法

 6. 下面我们再来分析一下submit()和execute()的以及shutdown()和shutdownNow()的区别

  • submit(),提交一个线程任务,可以接受回调函数的返回值吗,适用于需要处理返回着或者异常的业务场景
  • execute(),执行一个任务,没有返回值
  • shutdown(),表示不再接受新任务,但不会强行终止已经提交或者正在执行中的任务
  • shutdownNow(),对于尚未执行的任务全部取消,正在执行的任务全部发出interrupt(),停止执行

 7.  五种线程池的适应场景

  1. newCachedThreadPool:用来创建一个可以无限扩大的线程池,适用于服务器负载较轻,执行很多短期异步任务。
  2. newFixedThreadPool:创建一个固定大小的线程池,因为采用无界的阻塞队列,所以实际线程数量永远不会变化,适用于可以预测线程数量的业务中,或者服务器负载较重,对当前线程数量进行限制。
  3. newSingleThreadExecutor:创建一个单线程的线程池,适用于需要保证顺序执行各个任务,并且在任意时间点,不会有多个线程是活动的场景。
  4. newScheduledThreadPool:可以延时启动,定时启动的线程池,适用于需要多个后台线程执行周期任务的场景。
  5. newWorkStealingPool:创建一个拥有多个任务队列的线程池,可以减少连接数,创建当前可用cpu数量的线程来并行执行,适用于大耗时的操作,可以并行来执行
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值