文章目录
前言
本文基于个人理解对Future异步任务的执行流程及原理进行简单的总结。一、Future基本应用及基本构造
FutureTask的基本UML图。
1.基本应用
public class TestFutrueTask {
private static class PrintTask implements Callable<String>{
private String name;
public PrintTask(String name){
this.name=name;
}
@Override
public String call() throws Exception {
System.out.println("task running");
return name+" in task";
}
}
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(2);
Future<String> future = executorService.submit(new PrintTask("哈哈"));
try {
String s = future.get();
System.out.println(s);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
二、执行流程分析
1.executorService.submit(new PrintTask(“哈哈”))
AbstractExecutorService
public <T> Future<T> submit(Callable<T> task) {
if (task == null) throw new NullPointerException();
// 创建futureTask实例
RunnableFuture<T> ftask = newTaskFor(task);
// 在线程池中异步执行
execute(ftask);
// 直接返回ft实例
return ftask;
}
protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
return new FutureTask<T>(callable);
}
2.异步任务执行execute(ftask)
线程池执行流程参照ThreadPoolExcutor基本执行流程。
ThreadPoolExecutor中开启任务,假设线程池第一次添加任务,最终会来到addWorker的方法中
private boolean addWorker(Runnable firstTask, boolean core) {
retry:
for (;;) {
int c = ctl.get();
int rs = runStateOf(c);
// Check if queue empty only if necessary.
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(); // Re-read ctl
if (runStateOf(c) != rs)
continue retry;
// else CAS failed due to workerCount change; retry inner loop
}
}
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 {
// Recheck while holding lock.
// Back out on ThreadFactory failure or if
// shut down before lock acquired.
int rs = runStateOf(ctl.get());
if (rs < SHUTDOWN ||
(rs == SHUTDOWN && firstTask == null)) {
if (t.isAlive()) // precheck that t is startable
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;
}
开启异步任务执行后最终将执行FutureTask的run方法。
3.FutureTask的run
public void run() {
// 判断线程任务的状态及线程同步设置
if (state != NEW ||
!UNSAFE.compareAndSwapObject(this, runnerOffset,
null, Thread.currentThread()))
return;
try {
// 创建task时的线程任务
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 must be non-null until state is settled to
// prevent concurrent calls to run()
runner = null;
// state must be re-read after nulling runner to prevent
// leaked interrupts
int s = state;
if (s >= INTERRUPTING)
handlePossibleCancellationInterrupt(s);
}
}
protected void set(V v) {
// cas设置任务执行state为正在执行中
if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {
// 到时候get()取的就是这个值
outcome = v;
UNSAFE.putOrderedInt(this, stateOffset, NORMAL); // final state
// 唤起等待的线程
finishCompletion();
}
}
private void finishCompletion() {
// assert state > COMPLETING;
for (WaitNode q; (q = waiters) != null;) {
if (UNSAFE.compareAndSwapObject(this, waitersOffset, q, null)) { // cas成功
for (;;) { // 唤起所有等待的线程
Thread t = q.thread;
if (t != null) {
q.thread = null;
// 唤起等待线程
LockSupport.unpark(t);
}
WaitNode next = q.next;
if (next == null)
break;
q.next = null; // unlink to help gc
q = next;
}
break;
}
}
done();
callable = null; // to reduce footprint
}
4.FutureTask的get
当异步任务开启后,就在其他线程中通过get方法获取异步任务的执行结果。
public V get() throws InterruptedException, ExecutionException {
int s = state;
// 如果任务还没有完成则要进行阻塞等待
if (s <= COMPLETING)
// 这里是无限等待或在线程中执行终端操作
s = awaitDone(false, 0L);
return report(s);
}
private int awaitDone(boolean timed, long nanos)
throws InterruptedException {
final long deadline = timed ? System.nanoTime() + nanos : 0L;
WaitNode q = null;
boolean queued = false;
for (;;) { // 自旋至超时或完成任务
if (Thread.interrupted()) {// 线程中断
removeWaiter(q);
throw new InterruptedException();
}
int s = state;
if (s > COMPLETING) { // 任务完成
if (q != null)
q.thread = null;
return s;
}
// 在执行中则主动暗示放弃cpu
else if (s == COMPLETING) // cannot time out yet
Thread.yield();
else if (q == null)// 第一个循环的时候创建q
q = new WaitNode();
else if (!queued) // 第一次循环设置waiters
queued = UNSAFE.compareAndSwapObject(this, waitersOffset,
q.next = waiters, q);
else if (timed) { // 如果设置了超时等待时间
nanos = deadline - System.nanoTime();
if (nanos <= 0L) { // 超时了 后面便抛超时异常
removeWaiter(q);
return state;
}
LockSupport.parkNanos(this, nanos); // 直接阻塞超时设置
}
else // 没有超时设置则无限等待
LockSupport.park(this);
}
}
private V report(int s) throws ExecutionException {
Object x = outcome;
if (s == NORMAL) // 完成了任务就返回值
return (V)x;
if (s >= CANCELLED)
throw new CancellationException();
throw new ExecutionException((Throwable)x);
}
总结
以上基于个人理解,仅供参考,欢迎交流。