Excutor接口:只提供了void execute(Runnable command)方法;
ExecutorService接口:提供了shutdown、submit、invokeAll、invokeAny等方法;
ScheduledExecutorService 接口:以Schedule命名的接口或类与定时有关
线程池的核心类ThreadPoolExecutor :常见的四种类型的线程池都是该类型;
Executors:工具类:对外提供多种线程池
ThreadPoolExecutor 构造方法如下:
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
corePoolSize:核心线程数量,当线程数量小于核心线程数时,线程池会立即执行新来的任务;
maximumPoolSize:最大线程数;
keepAliveTime:空闲线程的存活时间;
workQueue:任务队列,用于缓存未执行的任务;
threadFactory:线程工厂。可通过工厂为新建的线程设置更有意义的名字
handler:拒绝策略,决定了线程池饱和时以怎样的方式拒绝新的任务,默认直接抛出异常;
1.线程数量小于 corePoolSize,直接创建新线程处理新的任务
2. 线程数量大于等于 corePoolSize,workQueue未满,则缓存新任务
3.线程数量大于等于 corePoolSize,但小于 maximumPoolSize,且 workQueue 已满。则创建新线程处理新任务
4.线程数量大于等于 maximumPoolSize,且 workQueue 已满,则使用拒绝策略处理新任务
Executors.newSingleThreadExecutor(); //线程数固定为1
Executors.newFixedThreadPool(int nThreads); //线程数固定为n
Executors.newCachedThreadPool(); //线程数不固定,空闲线程存活时间60s
Executors.newScheduledThreadPool(int nThreads); //核心线程数为n
//线程池正常运行的状态
private static final int RUNNING = 111;
//线程池调用了shutdown会切换到此状态,在该状态下不会接受新的任务,但是池中的任务会继续执行
private static final int SHUTDOWN = 000;
//线程池执行了shutdownNow会切换到此状态,在该状态下不会接受新的任务,池中的任务也会中断
private static final int STOP = 001;
//线程池中没有任务切换到这个状态
private static final int TIDYING = 010;
//线程执行了terminated方法会切换到这个状态
private static final int TERMINATED = 011;
1.使用线程必须通过线程池,不允许在应用中自行显式创建线程;
2.线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方 式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。
Executors返回的线程池对象的弊端如下:
1)FixedThreadPool 和 SingleThreadPool : 允许的请求队列长度为Integer.MAX_VALUE,可能会堆积大量的请求,从而导致OOM;
2) CachedThreadPool 和 ScheduledThreadPool:允许的创建线程数量为 Integer.MAX_VALUE,可能会创建大量的线程,从而导致OOM
ThreadPoolExecutor.execute:
//该整数高三位表示线程池状态,低29位记录线程池中线程数量
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
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();
}
//执行到这里,说明核心线程数已经达到上限
//线程池处于RUNNING状态,将任务添加到阻塞队列
if (isRunning(c) && workQueue.offer(command)) {
int recheck = ctl.get();
//二次检查线程池状态,如果发现线程池不处于RUNNING状态,就从阻塞队列中移除并reject该任务,
if (!isRunning(recheck) && remove(command))
reject(command);
//如果worker的数量为0,创建一个空的worker
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
//执行到这里,说明线程处于非RUNNING状态,所以直接reject任务就好了
else if (!addWorker(command, false))
reject(command);
}
ThreadPoolExecutor.execute:
//实际上核心Worker和非核心Worker都放在这里,并没有什么区别
private final HashSet<Worker> workers = new HashSet<>();
private boolean addWorker(Runnable firstTask, boolean core) {
retry:
for (;;) {
int c = ctl.get();
int rs = runStateOf(c);
//线程池处于非RUNNIND状态,直接return false
if (rs >= SHUTDOWN && !(rs == SHUTDOWN && firstTask == null && ! workQueue.isEmpty()))
return false;
for (;;) {
//获取worker的数量
int wc = workerCountOf(c);
//如果当前worker的数量超过了 核心线程上限 或 线程总容量,return false
if (wc >= CAPACITY || wc >= (core ? corePoolSize : maximumPoolSize))
return false;
// worker数量经过检查,数量复合要求,跳出循环执行下面的逻辑
if (compareAndIncrementWorkerCount(c))
break retry;
c = ctl.get();
//线程池状态如果发生了变化还要继续循环
if (runStateOf(c) != rs)
continue retry;
}
}
boolean workerStarted = false;
boolean workerAdded = false;
Worker w = null;
try {
//创建一个Worker
w = new Worker(firstTask);
//获取Worker的Thread成员
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)) {
//发现这个worker的线程已经在跑了,直接抛出异常
if (t.isAlive()) throw new IllegalThreadStateException();
//workers所有Worker组成的一个set,添加新建的worker
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;
}
ThreadPoolExecutor # Worker
private final class Worker extends AbstractQueuedSynchronizer implements Runnable {
//一个Worker与一个Thread是一一对应的,同一个Worker的Thread中会执行不同的Runnable任务
final Thread thread;
Runnable firstTask;
Worker(Runnable firstTask) {
setState(-1);
this.firstTask = firstTask;
this.thread = getThreadFactory().newThread(this);
}
public void run() {
runWorker(this);
}
final void runWorker(Worker w) {
Thread wt = Thread.currentThread();
//这里获取到task后,马上清除当前Worker的task,于是Worker变成了一只没有任务的Worker
Runnable task = w.firstTask;
w.firstTask = null;
w.unlock();
boolean completedAbruptly = true;
try {
//如果rask不为空,或者从阻塞队列中可以拿到任务
while (task != null || (task = getTask()) != null) {
w.lock();
//发现线程池的状态是STOP,就打断正在执行的任务
if ((runStateAtLeast(ctl.get(), STOP) || (Thread.interrupted() &&
runStateAtLeast(ctl.get(), STOP))) && !wt.isInterrupted())
wt.interrupt();
try {
beforeExecute(wt, task);
Throwable thrown = null;
try {
//这里在当前的线程执行任务,这里的task实际上就是我们execute方法传入的参数
task.run();
} catch (RuntimeException x) {
thrown = x; throw x;
} finally {
afterExecute(task, thrown);
}
} finally {
task = null;
w.completedTasks++;
w.unlock();
}
}
completedAbruptly = false;
} finally {
processWorkerExit(w, completedAbruptly);
}
}
}
ThreadPoolExecutor.getTask
private Runnable getTask() {
boolean timedOut = false; // Did the last poll() time out?
for (;;) {
int c = ctl.get();
int rs = runStateOf(c);
//线程已经不在RUNNING状态,或者阻塞队列已经为空,返回一个空任务
if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
decrementWorkerCount();
return null;
}
int wc = workerCountOf(c);
// 如果允许核心线程销毁,或者Worker数量大于核心线程数量,开启Worker销毁权限
boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;
if ((wc > maximumPoolSize || (timed && timedOut)) && (wc > 1 || workQueue.isEmpty())) {
if (compareAndDecrementWorkerCount(c))
return null;
continue;
}
try {
Runnable r = timed ?
//keepAliveTime时间内没有任务,返回null
workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
//阻塞式地等待队列中的任务并返回
workQueue.take();
if (r != null)
return r;
timedOut = true;
} catch (InterruptedException retry) {
timedOut = false;
}
}
}
使用submit提交任务:
public void main(){
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<String> future = executor.submit(new Task());
try {
Log.e(TAG, ""+System.currentTimeMillis()); //time = 0
String result = future.get(); //阻塞当前线程
Log.e(TAG, System.currentTimeMillis() + result); //time = 2
} catch (Exception e) {
e.printStackTrace();
}
}
class Task implements Callable<String> {
@Override
public String call() {
try {
Thread.sleep(20000);
} catch (Exception e) {
e.printStackTrace();
}
return "hello world";
}
}
AbstractExecutorService.submit:
public Future<?> submit(Runnable task) {
if (task == null) throw new NullPointerException();
// 通过submit方法提交的Callable任务会被封装成了一个FutureTask对象。
RunnableFuture<Void> ftask = newTaskFor(task, null);
execute(ftask);
return ftask;
}
protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
return new FutureTask<T>(runnable, value);
}
FutureTask:
public class FutureTask<V> implements RunnableFuture<V> {
private volatile int state;
private static final int NEW = 0;
private static final int COMPLETING = 1;
private static final int NORMAL = 2;
private static final int EXCEPTIONAL = 3;
private static final int CANCELLED = 4;
private static final int INTERRUPTING = 5;
private static final int INTERRUPTED = 6;
public FutureTask(Runnable runnable, V result) {
this.callable = Executors.callable(runnable, result);
this.state = NEW; // ensure visibility of callable
}
public V get() throws InterruptedException, ExecutionException {
int s = state;
if (s <= COMPLETING)
//阻塞式地等待任务执行完毕
s = awaitDone(false, 0L);
//向上层报告并返回结果
return report(s);
}
public void run() {
if (state != NEW || !U.compareAndSwapObject(this, RUNNER, null, Thread.currentThread()))
return;
try {
Callable<V> c = callable;
if (c != null && state == NEW) {
V result;
boolean ran;
try {
result = c.call();
ran = true;
} catch (Throwable ex) {
result = null;
ran = false;
setException(ex);
}
if (ran) set(result);
}
} finally {
runner = null;
int s = state;
if (s >= INTERRUPTING) handlePossibleCancellationInterrupt(s);
}
}
}
FutureTask.get
public V get() throws InterruptedException, ExecutionException {
int s = state;
if (s <= COMPLETING)
//这是一个阻塞方法,等待任务完成
s = awaitDone(false, 0L);
return report(s);
}