线程池
线程池分两种:
普通线程池——ThreadPoolExecutor
定时线程池——ScheduledThreadPoolExecutor
当前线程数还没有达到 corePoolSize 之前,新任务总是会 new 一个新的线程出来。当达到 corePoolSize 之后,任务就会入 workQueue,workQueue 满了之后就会再新建线程来消费 workQueue 中的任务,还有再多的任务过来的话,就会使用拒绝策略
线程池详解:
https://mp.weixin.qq.com/s/baYuX8aCwQ9PP6k7TDl2Ww
http://www.ideabuffer.cn/2017/04/04/%E6%B7%B1%E5%85%A5%E7%90%86%E8%A7%A3Java%E7%BA%BF%E7%A8%8B%E6%B1%A0%EF%BC%9AThreadPoolExecutor/
1. 线程池如何实现线程的复用?
执行一个 command 任务的时候,会有如下的调用链:
1. ExecutorService#execute() --> ThreadPoolExecutor#execute() 1.1 java.util.concurrent.ThreadPoolExecutor#addWorker // 增加一个 worker,即增加一个线程 1.1.1 java.util.concurrent.ThreadPoolExecutor.Worker#run() // start 线程时调用了 Worker#run() 1.1.1.1 java.util.concurrent.ThreadPoolExecutor#runWorker()
2. 线程池如何回收 idle 线程?
1. java.util.concurrent.ThreadPoolExecutor#runWorker() 1.1 java.util.concurrent.ThreadPoolExecutor#processWorkerExit() 1.1.1 java.util.concurrent.ThreadPoolExecutor#tryTerminate() 1.1.1.1 java.util.concurrent.ThreadPoolExecutor#interruptIdleWorkers(ONLY_ONE) // 通过 Thread#interrupt() 回收空闲的线程
回收空闲线程:
add: 2020.9.25
Tomcat 和 Dubbo 对线程池的改造:
主要思路是扩展 ThreadPoolExecutor 和 workerQueue(BlockingQueue)
com.alibaba.dubbo.common.threadpool.support.eager.EagerThreadPoolExecutor (重写 execute(),记录总任务数)
com.alibaba.dubbo.common.threadpool.support.eager.TaskQueue (重写 offer(),利用 offer() 返回 false 就会 addWorker 增加工作线程的逻辑)