线程池--jdk和tomcat线程池

1. jdk线程池:

创建方式:

线程池--jdk和tomcat线程池_第1张图片

线程池--jdk和tomcat线程池_第2张图片

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

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

 线程池--jdk和tomcat线程池_第3张图片

(1) Executors.newCachedThreadPool();

线程池--jdk和tomcat线程池_第4张图片

(2) Executors.newFixedThreadPool(100)

 线程池--jdk和tomcat线程池_第5张图片

(3) Executors.newScheduledThreadPool(100)

最终还是回溯到ThreadPoolExecutor

 线程池--jdk和tomcat线程池_第6张图片

(4) Executors.newSingleThreadExecutor()

 线程池--jdk和tomcat线程池_第7张图片


2. tomcat线程池:

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

线程池--jdk和tomcat线程池_第8张图片线程池--jdk和tomcat线程池_第9张图片


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

最好自定义拒绝执行策略(实现RejectedExecutionHandler),然后在策略代码中记录日志,然后在非高峰期使用定时任务解析日志信息,并作出相应处理;也可以在策略代码中使用HTTPClient向调用方发起请求说明情况(不建议:高峰期再增加这种额外负担不划算);还可以把超出的任务缓存下来,等空闲时再去处理,但是这样的话为什么不一开始就给一个比较大的有界队列。

你可能感兴趣的:(java开发)