java引入线程池的目的是为了复用线程,因为线程的创建和销毁都需要时间开销.
创建线程池的方法有很多种:
ExecutorService service = Executors.newCachedThreadPool();
ExecutorService service1 = Executors.newCachedThreadPool(new ThreadFactoryImpl("th"));
ExecutorService service2 = Executors.newFixedThreadPool(10);
ExecutorService service3 = Executors.newFixedThreadPool(10, new ThreadFactoryImpl("th"));
ExecutorService service4 = Executors.newSingleThreadExecutor();
ExecutorService service5 = Executors.newSingleThreadExecutor(new ThreadFactoryImpl("th"));
.......
但是这几个方法最终调用的都是ThreadPoolExecutor构造方法,只是参数不一样。线程池有几个重要的参数:
corePoolSize:核心线程数
maximumPoolSize:最大线程数,当核心线程数饱和并且任务队列也饱和,对继续创建新的工作线程继续处理任务
keepAliveTime:空闲线程的存活时间
workQueue:任务队列
allowCoreThreadTimeOut:If false (default), core threads stay alive even when idle. If true, core threads use keepAliveTime to time out waiting for work(源码注释).
handler:拒绝策略,当新添加的任务无法执行的时候,由策略类处理
threadFactory:线程工厂,用来生产线程
runState:线程池的状态 (COUNT_BITS = Integer.SIZE - 3)
RUNNING = -1 << COUNT_BITS;可接受新的任务,并且处理队列中的任务
SHUTDOWN = 0 << COUNT_BITS;不接受新的任务,但是会处理队列中的任务
STOP = 1 << COUNT_BITS;不接受新的任务,不处理队列中的任务,并且中断正在处理的任务
TIDYING = 2 << COUNT_BITS;所有的任务已经中断,工作线程数workerCount为0
TERMINATED = 3 << COUNT_BITS;结束
workerCount:工作线程数
ctl:AtomicInteger原子性整型变量,包含了线程池的状态和工作线程数量
Worker:工作线程,新添加的线程由worker类包装
其中线程池和工作线程数的判断都是通过位运算得到的,对位运算不同的朋友可以参考我的另外一篇文章java位运算
先贴上我画的一个流程图,供大家参考,往线程池中提交一个任务最终调用的是execute方法,下面是该方法的处理流程图:https://www.processon.com/view/link/5b4ebc83e4b067df59de9063
![](https://i-blog.csdnimg.cn/blog_migrate/0732312395dd80411a20ee3cd91bfadb.png)
添加工作线程是在addWorker方法中做的,后续会补齐该方法的处理过成和具体的流程图,敬请期待!!!