通过源码角度看java线程池
如有侵权,请联系!如果错误,请批评指正~
1、线程池提交一个任务流程
1.1、整体流程图概述
在查看源码之前,还是先看下整体的调用流程图,有个直观的感受。
线程池提交任务的流程:
1、提交任务:
调用线程池的 execute(Runnable command) 方法提交一个 Runnable 对象。
2、核心线程数判断:
首先,线程池会检查当前活跃线程的数量是否小于 corePoolSize。
3、创建新线程:
如果线程数小于 corePoolSize,则会创建一个新的线程来执行提交的 Runnable 任务。
4、任务入队尝试:
如果当前活跃线程数大于或等于 corePoolSize,则会尝试将 Runnable 加入到工作队列(workQueue)中。
5、正常入队:
如果工作队列未满,则将 Runnable 正常入队,进入等待任务执行的状态。
6、工作队列满的处理:
如果工作队列已满,加入队列失败,线程池将继续尝试增加线程来处理任务。
7、最大线程数判断:
线程池会判断当前活跃线程的数量是否小于 maximumPoolSize。
8、创建新线程执行任务:
如果当前线程数小于 maximumPoolSize,则会创建新的线程来执行该任务。
9、执行拒绝策略:
如果当前活跃线程数已经达到或超过 maximumPoolSize,则会执行拒绝策略(RejectedExecutionHandler),对提交的 Runnable 进行拒绝处理。
1.2、ThreadPoolExecutor源码
先看下ThreadPoolExecutor继承关系:
public interface Executor {
// 最底层接口,就表示执行任务
void execute(Runnable command);
}
public abstract class AbstractExecutorService implements ExecutorService {
// 提供了submit()方法,该方法会将任务封装成FutureTask,最终还是调用execute()方法执行任务。
// 因此,ThreadPoolExecutor只需要重写execute()方法
public Future<?> submit(Runnable task) {
if (task == null) throw new NullPointerException();
RunnableFuture<Void> ftask = newTaskFor(task, null);
execute(ftask);
return ftask;
}
public <T> Future<T> submit(Callable<T> task) {
if (task == null) throw new NullPointerException();
RunnableFuture<T> ftask = newTaskFor(task);
execute(ftask);
return ftask;
}
protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
return new FutureTask<T>(callable);
}
}
这里只是挑选ThreadPoolExecutor重要的属性和方法进行阐述。
public class ThreadPoolExecutor extends AbstractExecutorService {
// ctl高三位表示线程池的状态,后面表示线程池中线程的数量
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
private static final int COUNT_BITS = Integer.SIZE - 3;
private static final int CAPACITY = (1 << COUNT_BITS) - 1;
// runState is stored in the high-order bits
// 前三位不同的值表示线程池不同的状态
private static final int RUNNING = -1 << COUNT_BITS;
private static final int SHUTDOWN = 0 << COUNT_BITS;
private static final int STOP = 1 << COUNT_BITS;
private static final int TIDYING = 2 << COUNT_BITS;
private static final int TERMINATED = 3 << COUNT_BITS