jdk的线程池
原来的代码:
ThreadPoolExecutor aliGetTaskThreadPool = new ThreadPoolExecutor(4, 8, 0L,
TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<>(),
new ThreadFactoryBuilder().setNameFormat("VideoConvertDispatcher-aliGetTaskThreadPool-%d")
.build());
因为设置了线程池的maximumPoolSize为8,我以为提交任务比较多时,会生成8个线程,结果在测试中发现始终都只有4个线程在跑。后来发现是我理解错了(以前背的八卦文忘了好多了-_-)。正确答案应该是当线程数大于corePoolSize数量,并且等待队列已满,但是还没有达到最大线程数maximumPoolSize,则线程池才会创建新的“非核心线程”来执行任务。在这里因为等待队列无界,所以自然线程数不会超过corePoolSize 4. 于是我又做了个验证实验,把LinkedBlockingQueue改为了SynchronousQueue,果然此时线程数能达到8个了。
简单来说,就是先maximumPoolSize再等待队列的理解是错误的。应该是先存等待队列,等待队列满了才会生成新线程,直到线程数量超过maximumPoolSize则执行拒绝策略。
参考:
If there are more than corePoolSize but less than maximumPoolSize threads running, a new thread will be created only if the queue is full.
tomcat等的线程池
1Tomcat 的线程池。。。只是对 jdk 线程池做了简单优化。。。当线程池没有达到最大执行线程的时候,会优先开线程再使用任务队列;
2tomcat线程池策略和Dubbo的饥饿线程池逻辑差不多,只是实现不同。因为应用服务器或者RPC注重响应时间和资源占用,资源占用越少越好,响应时间越短越好,吞吐量越大越好。而jdk线程池,在核心线程用完后,就只能通过添加阻塞队列,而tomcat和dubbo为了保证响应速度,工作线程数只要不大于最大线程数,优先创建线程,创建不了了才会添加到阻塞对列中。