线程池(二)

线程池介绍

1、常用线程池

       官方建议使用Executors工厂方法提供的线程池。newFixedThreadPool、newSingleThreadExecutor、newCachedThreadPool、newSingleThreadScheduledExecutor、newScheduledThreadPool。以上线程池覆盖大部分场景,如果因业务需求,需详细配置可以继续阅读,了解线程池的使用方法和原理。

2、初始化参数

       ThreadPoolExecutor四个构造函数由以下不同参数去实例化,需要特殊配置线程池需要使用以下七个参数。以下是参数介绍及使用介绍。

corePoolSize:核心线程数。线程池保有线程数量(即使线程是闲置的),如果设置allowCoreThreadTimeOut=true(默认false),闲置线程等待指定存活时间,若无任务,则终止。默认情况下线程池初始化后线程数量=0,只有新任务提交时才会创建线程。

       当然线程池也提供了另外三个创建线程的方式:prestartCoreThread(创建一个核心闲置线程等待新任务,如果所有核心线程已经被创建,方法返回false)、ensurePrestart(同prestartCoreThread,特殊处是核心线程数=0时,仍保证创建至少一个线程)、prestartAllCoreThreads(创建所有的核心限制线程),三个方法都覆盖了默认有新任务时创建线程的策略。当任务队列不为空时,则可以使用三种策略预先启动新线程。

maxMumPoolSize:最大线程数。线程池允许的最大线程数量。可以设置为基本无界值(如Integer.MAX_VALUE),则将适应任意数量的并发任务,但也会带来很多弊端。

keepAliveTime:线程存活时间。线程数>corePoolSize,闲置线程在终止前等待新任务的时间。默认情况下,当线程数超过核心线程数,存活时间才会起作用,即只作用于非核心线程。等待新任务时间超过存活时间,线程则中止,直至线程数<corePoolSize。若线程池设置了allowCoreThreadTimeOut=true,线程等不到新任务,超过存活时间终止,直至线程数=0。

TimeUnit:存活时间单位。枚举类java.util.concurrent.TimeUtil提供纳秒~天

BlockingQueue:任务队列(阻塞)。线程任务(由execute提交的Runnable类型任务)被执行前存放在该阻塞队列。BlockingQueue目前的实现类如下(jdk 1.7),常用队列ArrayBlockIng、LinkedBlockingQueue。排队策略:无界队列(如LinkedBlockingQueue不初始化容量),有界队列(ArrayBlockIng),直接提交(默认选项是 SynchronousQueue)。三种队列的特性将会影响线程池的初始配置和运行,将会在线程池配置详细说明。:队列类的特性及相关知识,可查看容器类介绍。

ThreadFactory:线程工厂。创建新线程的工程。默认使用Executors.defaultThreadFactory创建线程,且线程优先级(NORM_PRIORITY )和非守护进程状态相同。自定义ThreadFactory可以改变线程优先级等。

RejectedExceptionHandler:线程池拒绝异常处理器。线程数量超过线程池承载,会报此异常,表示线程池拒绝处理。线程池拒绝新任务后的操作。默认线程池抛出RejectedExecutionException(Java线程池提供了四种异常策略,可见于线程池类注释)。可自定义,实现RejectedExecutionHandler接口,重写rejectedExecution方法即可。

3、其它特性

hook钩子

队列维护

中止

Executors提供的几类线程池初始化参数也是使用以上七个,只是场景不同,参数值不同。

4、原理

4.1 工作流程:

 

(1)通过ThreadPoolExecutor.execute提交任务,当小于corePoolSize时,即使有空闲的线程,仍会开启一个新线程,且任务不会进入队列排队。原子操作addWorker会检查runState和workerCount,无法添加时会报异常。

(2)当线程数大于核心线程数(workerCount>=corePoolSize),新任务会先添加到任务队列(BlookingQueue)排队等待。添加任务时仍然需要仔细核查线程池的状态(runState)以及当线程入队后状态不满足是否回滚入队任务。

(3)当任务无法入队,corePoolSize<线程数量<maxMumPoolSize会创建一个新线程,当大于最大线程数且队列已满,则会抛出异常,无法执行任务。

4.2 核心方法

(1)构造方法

ThreadPoolExecutor有四个构造方法,构造方法只是参数个数不同,按需构造。

(2)提交任务

 

5、线程池使用介绍

线程池提供的方法参考:http://tool.oschina.net/apidocs/apidoc?api=jdk-zh

怎么用-原理-注意事项

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值