线程池
1 | ThreadPoolExecutor(int corePoolSize, |
- corePoolSize 线程池核心线程数最大值,核心线程默认情况下即使在没有工作时也会保留
- maximumPoolSize 线程池最大线程数大小
- keepAliveTime 非核心线程空闲的存活时间大小
- unit 线程空闲存活时间单位
- workQueue 用于存放任务的阻塞队列,核心线程满时新任务先放入阻塞队列,队列满时再创建非核心线程,如果超过最大线程数,则抛出异常
- threadFactory线程工厂,主要用来创建线程,比如可以指定线程的名字
- handler 当队列和最大线程池都满了之后的饱和策略,主要有四种类型
使用
通过execute(Runnable command)方法来向线程池提交任务
1 | import java.util.concurrent.ExecutorService; |
常见线程池
newCachedThreadPool
1 | public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) { |
- corePoolSize => 0,核心线程池的数量为0
- maximumPoolSize => Integer.MAX_VALUE,线程池最大数量为Integer.MAX_VALUE,可以认为可以无限创建线程
- keepAliveTime => 60L
- unit => 秒
- workQueue => SynchronousQueue
- 因为Integer.MAX_VALUE非常大,可以认为是可以无限创建线程的,在资源有限的情况下容易引起OOM异常。由于空闲 60 秒的线程会被终止,长时间保持空闲的 CachedThreadPool 不会占用任何资源。
- 用于并发执行大量短期的小任务
newFixedThreadPool
1 | public static ExecutorService newFixedThreadPool(int nThreads) { |
FixedThreadPool是固定核心线程的线程池,固定核心线程数由用户传入
- corePoolSize => nThreads
- maximumPoolSize => nThreads,线程池最大数量为nThreads,即最多只可以创建nThreads个线程
- keepAliveTime => 0L
- unit => 毫秒
- workQueue => LinkedBlockingQueue
- 使用的是LinkedBlockingQueue,在资源有限的时候容易引起OOM异常
- FixedThreadPool 适用于处理CPU密集型的任务,确保CPU在长期被工作线程使用的情况下,尽可能的少的分配线程,即适用执行长期的任务。
newSingleThreadExecutor
1 | public static ExecutorService newSingleThreadExecutor() { |
- 核心线程数为1
- 最大线程数也为1
- 阻塞队列是LinkedBlockingQueue
- keepAliveTime为0
- 适用于串行执行任务的场景,一个任务一个任务地执行。
newScheduledThreadPool
1 | public ScheduledThreadPoolExecutor(int corePoolSize, |
- 最大线程数为Integer.MAX_VALUE
- 阻塞队列是DelayedWorkQueue
- keepAliveTime为0
- scheduleAtFixedRate() :按某种速率周期执行
- scheduleWithFixedDelay():在某个延迟后执行
- 周期性执行任务的场景,需要限制线程数量的场景
原理
线程池的状态
线程池有5种状态
- RUNNING,接收新任务,处理缓存的任务
- SHUTDOWN,不接受新任务,但处理缓存的任务
- STOP,不接受新任务,不处理缓存的任务,中断正在执行的任务
- TIDYING,所有线程都已终止,有效线程为0,触发_terminated()_方法
- TERMINATED,_terminated()_方法结束
线程池的状态通过一个AtomicInteger来实现,使用3位来代表状态,剩下的位用于统计线程数。线程使用Worker来包装。
源码
1 | public void execute(Runnable command) { |
再看addWorker方法
1 | /** |
addWorker之后,调用worker中Thread的start方法,start方法又调用worker的run,worker中的run方法又调用runWorker方法,runWorker中最终调用task的run
1 | final void runWorker(Worker w) { |