您的位置:首页 > 运维架构 > Tomcat

线程池--jdk和tomcat线程池

2018-01-11 12:23 246 查看
1. jdk线程池:

创建方式:





有界队列:eg-- new ArrayBlockingQueue(10); 先拿任务数和corePoolSize比较,任务过多再去和队列比较,任务还多再去跟maximumPoolSize比较,最后执行拒绝策略。
无界队列:eg-- new LinkedBlockingQueue(); 默认的capacity为Integer.MAX_VALUE,除非重写,否则无界。阈值是corePoolSize,maximumPoolSize没意义。

jdk提供了Executors简单工厂去方便的生成线程池,不管哪种方式,线程池默认初始线程数都是0;但如果调用了线程池的prestartAllCoreThreads方法,线程池会提前创建并启动所有基本线程。

 


(1) Executors.newCachedThreadPool();



(2) Executors.newFixedThreadPool(100)

 


(3) Executors.newScheduledThreadPool(100)





最终还是回溯到ThreadPoolExecutor:

 


(4) Executors.newSingleThreadExecutor()

 


2. tomcat线程池:

tomcat线程池跟jdk线程池略有区别,它的TaskQueue是一个无界队列,为了使线程池的线程数能达到maximumPoolSize,它的offer方法做了一些改变,当线程数达到minSpareThreads(corePoolSize)后,需要向TaskQueue(默认的capacity为Integer.MAX_VALUE,除非重新赋值)中存储,但在offer方法存储过程中,如果发现线程数没有达到maximumPoolSize,就会新开线程去处理,而不再存入TaskQueue,除非达到maximumPoolSize才会存入队列。所以tomcat线程池虽然是无界队列,但它的线程数上限却是maximumPoolSize。





3. 线程池的拒绝执行策略:

最好自定义拒绝执行策略(实现RejectedExecutionHandler),然后在策略代码中记录日志,然后在非高峰期使用定时任务解析日志信息,并作出相应处理;也可以在策略代码中使用HTTPClient向调用方发起请求说明情况(不建议:高峰期再增加这种额外负担不划算);还可以把超出的任务缓存下来,等空闲时再去处理,但是这样的话为什么不一开始就给一个比较大的有界队列。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  线程池 tomcat jdk