6. 线程池
6.1 概念
线程池说的是提前创建好一批线程,然后保存在线程池中,当有任务需要执行的时候,从线程池中选一个线程来执行任务。
6.2 核心参数
(1) 核心线程数
(2) 最大线程数
(3) 任务等待队列
(4) 创建线程的工厂
(5) 线程池拒绝策略
(6) 非核心线程空闲时间
(7) 时间单位
6.3 向线程池中添加一个任务的流程
(1) 一开始线程池刚创建出来,里面没有线程。
(2) 如果正在运行的线程数<corePoolSize,马上创建线程执行该任务。
(3) 如果正在运行的线程数>=corePoolSize,把任务放进等待队列中。
(4) 如果等待队列已满并且正在运行的线程数<maximumPoolSize,创建新的线程执行该任务。
(5) 如果等待队列已满并且正在运行的线程数>=maximumPoolSize,执行拒绝策略。
6.4 线程池拒绝策略有哪几种
(1) AbortPolicy:任务会被拒绝执行,抛一个异常。
(2) DiscardPolicy:任务会被拒绝执行,不抛异常。
(3) DiscardOldestPolicy:会尝试把等待队列中最早的任务删除,然后再尝试提交新任务。
(4) CallerRunsPolicy:哪个线程提交任务,哪个线程执行任务。
6.5 为什么阿里禁止使用Executors创建线程池?
Executors创建的线程池允许创建的最大线程数是Integer.MAX_VALUE,或者等待队列的长度是Integer.MAX_VALUE,可能发生oom。
6.6 白天任务大,晚上任务小,如何设置线程数?
我们先会估算整个业务的一个场景,它的一个并发量是多少,然后可以不断压测,不断调整,最终达到一个相对合理的值。然后理论值的话,如果是cpu密集型应用,则线程池大小设置为N+1,如果是IO密集型应用,则设置为2N+1,当然这只是理论上的值,最后还要结合我们的压测结果。