示例提供
以这段代码为例, 下文讲述带返回值的线程池处理流程。
// 新建一个线程池
private ExecutorService executor = new ThreadPoolExecutor(20, 50, 2, TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>(50), new ThreadPoolExecutor.CallerRunsPolicy());
Future<Boolean> future = executor.submit(new Callable<Boolean>() {
public Boolean call() throws Exception {
// ...
return true;
};
});
// 获取结果
Boolean res = future.get(timeout, TimeUnit.MILLISECONDS);
先说结论
**返回值存储在FutureTask类的内部变量outcome 中,设置返回值由FutureTask#run方法处理,获取返回值由FutureTask#get方法处理 **。
下面是FutureTask类一些重要的变量以及构造函数
/** The underlying callable; nulled out after running */
private Callable<V> callable;
/** The result to return or exception to throw from get() */
private Object outcome; // non-volatile, protected by state reads/writes
/** The thread running the callable; CASed during run() */
private volatile Thread runner;
/**
* 参数为callable
*/
public FutureTask(Callable<V> callable) {
if (callable == null)
throw new NullPointerException();
this.callable = callable;
this.state = NEW; // ensure visibility of callable
}
/**
* 参数为runnable
*/
public FutureTask(Runnable runnable, V result) {
this.callable = Executors.callable(runnable, result);
this.state = NEW; // ensure visibility of callable
}
相关UML图
设值流程
由ThreadPoolExecutor#submit开始提交线程
public <T> Future<T> submit(Callable<T> task) {
if (task == null) throw new NullPointerException();
RunnableFuture<T> ftask = newTaskFor(task);
execute(ftask);
return ftask;
}
由上面的构造函数可以看出此处参数也可以是runnable, 会通过Executors.callable(runnable, result)进行组装成callable。
再执行ThreadPoolExecutor#execute方法, 最后返回future对象。
那么看execute方法
public void execute(Runnable command) {
// ...
// 添加一个 worker来执行任务
addWorker(command, true))
// ...
}
private boolean addWorker(Runnable firstTask, boolean core) {
// ...
// 新建一个工作任务 执行
Worker w = new Worker(firstTask);
final Thread t = w.thread;
t.start();
// ...
}
Worker执行操作
private final class Worker
extends AbstractQueuedSynchronizer
implements Runnable
{
// ...
Worker(Runnable firstTask) {
setState(-1); // inhibit interrupts until runWorker
this.firstTask = firstTask;
this.thread = getThreadFactory().newThread(this);
}
/** Delegates main run loop to outer runWorker */
public void run() {
runWorker(this);
}
}
final void runWorker(Worker w) {
Thread wt = Thread.currentThread();
Runnable task = w.firstTask;
w.firstTask = null;
w.unlock(); // allow interrupts
boolean completedAbruptly = true;
try {
// task != null,直接执行该task
// task == null,getTask() 从工作队列中获取task
while (task != null || (task = getTask()) != null) {
w.lock();
try {
// 钩子函数,任务执行前的操作
beforeExecute(wt, task);
try {
// 任务执行
task.run();
} catch (RuntimeException x) {
...
} finally {
// 钩子函数,任务执行后的操作
afterExecute(task, thrown);
}
} finally {
task = null;
w.completedTasks++;
w.unlock();
}
}
completedAbruptly = false;
} finally {
//...
}
}
任务执行, 最终走到了FutureTask#run。 前面的细节流程可以看之前的一篇文章分析Java并发-线程池源码分析
public void run() {
if (state != NEW ||
!UNSAFE.compareAndSwapObject(this, runnerOffset,
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 {
// ...
}
}
protected void set(V v) {
if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {
// 将运行结果设值到属性outcome上
outcome = v;
UNSAFE.putOrderedInt(this, stateOffset, NORMAL); // final state
// 处理线程唤醒等操作
finishCompletion();
}
}
可以看到最终在Future#set方法处完成了异步结果的赋值。
取值流程
取值的流程相对简单, 直接Future#get方法获取。
/**
* 不带阻塞时间
*/
public V get() throws InterruptedException, ExecutionException {
int s = state;
// 异步操作未处理完成时, 进行阻塞等待
if (s <= COMPLETING)
s = awaitDone(false, 0L);
// 返回outcome 或者异常
return report(s);
}
/**
* 带阻塞时间
*/
public V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException {
if (unit == null)
throw new NullPointerException();
int s = state;
// 异步操作未处理完成时, 进行阻塞等待
if (s <= COMPLETING &&
(s = awaitDone(true, unit.toNanos(timeout))) <= COMPLETING)
throw new TimeoutException();
// 返回outcome 或者异常
return report(s);
}
【本文完】