一、简述
线程池维护着一定的线程数量,通过线程复用减少了线程频繁开启销毁的消耗。
当新任务提交到线程池时:
如果线程池中运行线程数量小于核心线程数量,启动新线程执行提交的任务。
如果线程池中运行线程数量大于或等于核心线程数量,且队列未满,将任务加入队列。此时再次检查,如果没有运行中的线程,启动新线程执行队列中的任务。
如果线程池中运行线程数量大于或等于核心线程数量,但小于最大线程数量,且队列已满,启动新线程执行队列中的任务。
如果线程池中运行线程数量等于最大线程数量,且队列已满,执行拒绝策略。
二、ThreadPoolExecutor属性
1. ctl&wc&rs
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;
// Packing and unpacking ctl
private static int runStateOf(int c) { return c & ~CAPACITY; }
private static int workerCountOf(int c) { return c & CAPACITY; }
private static int ctlOf(int rs, int wc) { return rs | wc; }
wc:workCount,可以理解为workCount,最多为2^29 - 1。
rs:runState,表示允许状态,对应RUNNING,SHUTDOWN,STOP,TIDYING,TERMINATED。
ctl:线程池的状态标志,由wc和rs组合而成。
2. handler
private volatile RejectedExecutionHandler handler;
private static final RejectedExecutionHandler defaultHandler = new AbortPolicy();
handler为RejectedExecutionHandler接口类型。
该接口只有1个方法:void rejectedExecution(Runnable r, ThreadPoolExecutor executor);
用于表示拒绝策略,当线程池中的任务数量超限时,新任务提交后将进入拒绝策略的逻辑。
ThreadPoolExecutor提供了4个RejectedExecutionHandler的实现类,分别是:
(1) AbortPlicy:抛异常RejectedExecutionException
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
throw new RejectedExecutionException("Task " + r.toString() +
" rejected from " +
e.toString());
}
(2)DiscardPolicy:不做任何处理
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
}
(3)DiscardOldestPolicy:放弃队列中的第一个任务,新任务加入队列
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
if (!e.isShutdown()) {
e.getQueue().poll();
e.execute(r);
}
}
(4)CallerRunsPolicy:直接执行新任务
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
if (!e.isShutdown()) {
r.run();
}
}
3. workQueue
workQueue为BlockingQueue类型
当线程池中核心线程数小于任务数时,会将提交的任务保存在workQueue中。
在线程池中主要使用了以下3类BlockingQueue。
(1)有界队列
这一类队列中存放的任务数量有限制,因此称为有界队列。
常用的有界队列是ArrayBlockingQueue和PriorityBlockingQueue,前者适合于FIFO的执行顺序的场景,后者适合于按照优先级的执行顺序的场景。
(2)无界队列
这一列队列中可以存放任意数量的任务,因此称为无界队列。
有用的无界队列为LinkedBlockingDeque
(3)同步队列
主要指SynchronousQueue,不存放任何的任务。
4. threadFactory
threadFactory类型为ThreadFactory接口,是Thread的工厂类,用于根据runnable生成thread。接口中只有一个方法:Thread newThread(Runnable r);
。
(1)DefaultThreadFactory
线程池中最常使用的ThreadFactory实现类是Executors的静态内部类DefaultThreadFactory。
static class DefaultThreadFactory implements ThreadFactory {
private static final AtomicInteger poolNumber = new AtomicInteger(1);
private final ThreadGroup group;
private final AtomicInteger threadNumber = new AtomicInteger(1);
private final String namePrefix;
DefaultThreadFactory() {
SecurityManager s = System.getSecurityManager();
group = (s != null) ? s.getThreadGroup() :
Thread.currentThread().getThreadGroup();
namePrefix = "pool-" +
poolNumber.getAndIncrement() +
"-thread-";
}
public Thread newThread(Runnable r) {
Thread t = new Thread(group, r,
namePrefix + threadNumber.getAndIncrement(),
0);
if (t.isDaemon())
t.setDaemon(false);
if (t.getPriority() != Thread.NORM_PRIORITY)
t.setPriority(Thread.NORM_PRIORITY);
return t;
}
}
(2)Worker
threadFactory在线程池中的用处就是在Worker的构造器中。
Worker是对提交到线程池的任务的封装。
Worker(Runnable firstTask) {
setState(-1); // inhibit interrupts until runWorker
this.firstTask = firstTask;
this.thread = getThreadFactory().newThread(this);
}
state设置为-1是为了防止中断方法
void interruptIfStarted() {
Thread t;
if (getState() >= 0 && (t = thread) != null && !t.isInterrupted()) {
try {
t.interrupt();
} catch (SecurityException ignore) {
}
}
}
</