Executor
Executor是线程池组件的顶层接口
只是定义了一个方法:
void execute(Runnable command);
有如下三个子类比较重要:
1. ExecutorService 继承 Executor接口
2. AbstractExecutorService 继承 ExecutorService接口
3. ThreadPoolExecutor 继承了 AbstractExecutorService抽象类
创建线程池
Executors是线程池工具类提供了如下创建线程池的方法
Executors是线程池工具类提供了如下创建线程池的方法
看了如下的静态方法,会发现都是使用的ThreadPoolExecutor的构造方法,只不过jdk帮助我们写死了部分操作参数
ThreadPoolExecutor 也是我们日常开发中 最常用的类,所有我们主要要看 ThreadPoolExecutor
Executors.newSingleThreadExecutor();
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
Executors.newFixedThreadPool(30);
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
Executors.newCachedThreadPool();
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
ThreadPoolExecutor基础信息
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
if (corePoolSize < 0 ||
maximumPoolSize <= 0 ||
maximumPoolSize < corePoolSize ||
keepAliveTime < 0)
throw new IllegalArgumentException();
if (workQueue == null || threadFactory == null || handler == null)
throw new NullPointerException();
this.acc = System.getSecurityManager() == null ?
null :
AccessController.getContext();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
ThreadPoolExecutor 构造方法参数含义
1. corePoolSize : 线程池中所一直维护的线程数量,如果线程池处于任务空闲期间,那么这些线程也不会被回收掉
2. maximumPoolSize : 线程池中所维护的线程最大数量
3. keepAliveTime : 超过了corePoolSize的线程在经过keepAliveTime时间后如果一直处于空闲状态,那么这些超过的线程要被回收掉
4. unit : 时间单位
5. workQueue : 向线程池所提交的任务位于的阻塞队列,他的实现有多种方式
6. threadFactory : 线程工工厂,用于创建新的线程并被线程池所管理,默认线程工厂所创建的线程都是用户线程且优先级为5
7. handler : 表示当前线程池中的线程都在执行任务并且等待队列也满了,那么对于新来的任务的拒绝策略,有如下四种
threadFactory
threadFactory就是给这个线程池创建线程的
假如你不实现使用的默认工厂 DefaultThreadFactory
DefaultThreadFactory
public Thread newThread(Runnable r) {
Thread t = new Thread(group, r,
namePrefix + threadNumber.getAndIncrement(),
if (t.isDaemon())
t.setDaemon(false);
if (t.getPriority() != Thread.NORM_PRIORITY)
t.setPriority(Thread.NORM_PRIORITY);
return t;
}
handler(拒绝策略) RejectedExecutionHandler
拒绝策略,有如下四种:
1. AbortPolicy 直接抛出运行时异常
2. DiscardPolicy 直接丢弃掉任务,就是空实现,也不抛出异常
3. DiscardOldestPolicy 丢弃阻塞队列中最早的一个任务,并且为当前所提交的任务留出一个队列中的位置,以便将其放入队列中
4. CallerRunsPolicy 直接在提交任务的线程上执行 , 就是 直接调用了 run 方法
5.也可以自定义处理
AbortPolicy
public static class AbortPolicy implements RejectedExecutionHandler {
public AbortPolicy() { }
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
throw new RejectedExecutionException("Task " + r.toString() +
" rejected from " +
e.toString());
}
}
DiscardPolicy
public static class DiscardPolicy implements RejectedExecutionHandler {
public DiscardPolicy() { }
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
}
}
DiscardOldestPolicy
public static class DiscardOldestPolicy implements RejectedExecutionHandler {
public DiscardOldestPolicy() { }
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
if (!e.isShutdown()) {
e.getQueue().poll();
e.execute(r);
}
}
}
CallerRunsPolicy
public static class CallerRunsPolicy implements RejectedExecutionHandler {
public CallerRunsPolicy() { }
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
if (!e.isShutdown()) {
r.run();
}
}
}
ThreadPoolExecutor 执行方法
ThreadPoolExecutor执行方法有如下四个:
1. <T> Future<T> submit(Callable<T> task) ExecutorService提供的抽象方法,AbstractExecutorService中实现
2. <T> Future<T> submit(Runnable task, T result) ExecutorService提供的抽象方法,AbstractExecutorService中实现
3. Future<?> submit(Runnable task); ExecutorService提供的抽象方法,AbstractExecutorService中实现
4. void execute(Runnable command) Executor接口提供的抽象方法,ThreadPoolExecutor实现
submit(Callable< T > task)
public <T> Future<T> submit(Callable<T> task) {
if (task == null) throw new NullPointerException();
RunnableFuture<T> ftask = newTaskFor(task);
execute(ftask);
return ftask;
}
RunnableFuture (有兴趣的可以看,不影响整体流程)
public interface RunnableFuture<V> extends Runnable, Future<V> {
void run();
}
newTaskFor -- FutureTask (有兴趣的可以看,不影响整体流程)
protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
return new FutureTask<T>(callable);
}
protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
return new FutureTask<T>(runnable, value);
}
public FutureTask(Callable<V> callable) {
if (callable == null)
throw new NullPointerException();
this.callable = callable;
this.state = NEW;
}
public FutureTask(Runnable runnable, V result) {
this.callable = Executors.callable(runnable, result);
this.state = NEW;
}
public static <T> Callable<T> callable(Runnable task, T result) {
if (task == null)
throw new NullPointerException();
return new RunnableAdapter<T>(task, result);
}
static final class RunnableAdapter<T> implements Callable<T> {
final Runnable task;
final T result;
RunnableAdapter(Runnable task, T result) {
this.task = task;
this.result = result;
}
public T call() {
task.run();
return result;
}
}
submit(Runnable< T > task)
public Future<?> submit(Runnable task) {
if (task == null) throw new NullPointerException();
RunnableFuture<Void> ftask = newTaskFor(task, null);
execute(ftask);
return ftask;
}
submit(Runnable task, T result)
public <T> Future<T> submit(Runnable task, T result) {
if (task == null) throw new NullPointerException();
RunnableFuture<T> ftask = newTaskFor(task, result);
execute(ftask);
return ftask;
}
线程池的执行流程
由上面的3个submit方法可以看出都是调用了execute方法,所以这是我们的重点
关于线程池的总体执行策略:
1..如果线程池中正在执行的线程数小于corePoolSize,那么线程池就会优先创建新的线程而不是将提交的任务放到阻塞队列中
2..如果线程池中正在执行的线程数大于或者等于corePoolSize,那么线程池会优先选择对提交的任务进行阻塞排队,而不是创建新的线程
3..如果提交的任务无法添加到阻塞队列中,那么线程池就会创建新的线程,如果创建的线程数超过了maximumPoolSize,那么就会触发拒绝策略
线程池存在5中状态:
1..RUNNING : 表示线程池可以接受新的任务的提交,并可以正常处理阻塞队列中的任务
2..SHUTDOWN : 表示线程池不在接受新的任务的提交,但是可以处理阻塞队列中的任务
3..STOP : 表示线程池不再接受新的任务,同时还会丢弃阻塞中的任务,还会中断正在这个执行的任务
4..TIDYING : 表示线程池中所有的任务都执行完毕后,当前线程中的活性的线程数降为0,将会调用terminated()
5..TERMINATED: 表示线程池的终止状态
关于线程池的有一些问题
1. 核心线程数是如何保持的
-- getTask()方法中从 workQueue 中获取任务的时候,根据 allowCoreThreadTimeOut(是否使用超时时间处理核心线程)
||
当前线程数量>核心线程数(由此可见大于核心线程数的会被回收)
2. 在任务执行之前打印日志
-- 在runWorker方法中存在 beforeExecute,afterExecute方法,如果需要可以在子类中实现
3. 核心线程会不会发生变化
-- 当线程执行异常时,会有补偿机制,创建新的线程替换
4. 超过keepAliveTime时间之后如何回收线程
-- 参考问题1
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;
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;
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; }
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
int c = ctl.get();
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true))
return;
c = ctl.get();
}
if (isRunning(c) && workQueue.offer(command)) {
int recheck = ctl.get();
if (! isRunning(recheck) && remove(command))
reject(command);
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
else if (!addWorker(command, false))
reject(command);
}
private boolean addWorker(Runnable firstTask, boolean core) {
retry:
for (;;) {
int c = ctl.get();
int rs = runStateOf(c);
if (rs >= SHUTDOWN &&
! (rs == SHUTDOWN &&
firstTask == null &&
! workQueue.isEmpty()))
return false;
for (;;) {
int wc = workerCountOf(c);
if (wc >= CAPACITY ||
wc >= (core ? corePoolSize : maximumPoolSize))
return false;
if (compareAndIncrementWorkerCount(c))
break retry;
c = ctl.get();
if (runStateOf(c) != rs)
continue retry;
}
}
boolean workerStarted = false;
boolean workerAdded = false;
Worker w = null;
try {
w = new Worker(firstTask);
final Thread t = w.thread;
if (t != null) {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
int rs = runStateOf(ctl.get());
if (rs < SHUTDOWN ||
(rs == SHUTDOWN && firstTask == null)) {
if (t.isAlive())
throw new IllegalThreadStateException();
workers.add(w);
int s = workers.size();
if (s > largestPoolSize)
largestPoolSize = s;
workerAdded = true;
}
} finally {
mainLock.unlock();
}
if (workerAdded) {
t.start();
workerStarted = true;
}
}
} finally {
if (! workerStarted)
addWorkerFailed(w);
}
return workerStarted;
}
Worker
class定义
private final class Worker
extends AbstractQueuedSynchronizer
implements Runnable
实现了Runnable
继承了AQS
Worker构造方法
Worker(Runnable firstTask) {
setState(-1);
this.firstTask = firstTask;
this.thread = getThreadFactory().newThread(this);
}
Worker.run()
public void run() {
runWorker(this);
}
final void runWorker(Worker w) {
Thread wt = Thread.currentThread();
Runnable task = w.firstTask;
w.firstTask = null;
w.unlock();
boolean completedAbruptly = true;
try {
while (task != null || (task = getTask()) != null) {
w.lock();
if ((runStateAtLeast(ctl.get(), STOP) ||
(Thread.interrupted() &&
runStateAtLeast(ctl.get(), STOP))) &&
!wt.isInterrupted())
wt.interrupt();
try {
beforeExecute(wt, task);
Throwable thrown = null;
try {
task.run();
} catch (RuntimeException x) {
thrown = x; throw x;
} catch (Error x) {
thrown = x; throw x;
} catch (Throwable x) {
thrown = x; throw new Error(x);
} finally {
afterExecute(task, thrown);
}
} finally {
task = null;
w.completedTasks++;
w.unlock();
}
}
completedAbruptly = false;
} finally {
processWorkerExit(w, completedAbruptly);
}
}