FutureTask的继承关系
FutureTask的WaitNode静态内部类,一个WaitNode代表一个等待线程(线程调用get()方法后被阻塞)。
FutureTask维护着waiters列表,是一个WaitNode的单向链表,当Runnable任务执行完后会调用finishCompletion方法,会唤醒所有被get()方法阻塞的线程。
FutureTask初始化方法
当使用Runnable初始化时,会将Runnable包装成一个返回Void的Callable.
public FutureTask(Callable<V> callable) {
if (callable == null)
throw new NullPointerException();
this.callable = callable;
this.state = NEW; // ensure visibility of callable
}
public FutureTask(Runnable runnable, V result){
this.callable = Executors.callable(runnable, result);
this.state = NEW; // ensure visibility of callable
}
//任务状态
/* Possible state transitions:
* NEW -> COMPLETING -> NORMAL
* NEW -> COMPLETING -> EXCEPTIONAL
* NEW -> CANCELLED
* NEW -> INTERRUPTING -> INTERRUPTED
*/
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;
FutureTask的run方法,执行任务,设置任务状态, 设置任务结果(唤醒等待的线程),有异常时也需要唤醒所有等待线程。
public void run() {
//如果任务状态不是NEW或者更新runner域失败(其他线程竞争),直接返回
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)
//1.将state从NEW设置为Completing
//2.将state从Completing设置为Normal
//3.唤醒等待线程
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;
//只有state是New时,调用cancel方法时,如果设置了mayInterrupteIfRunning,会把state设置成为interrupting,否则将state 设置为Cancelled
//如果任务状态是interrupt,则
if (s >= INTERRUPTING)
handlePossibleCancellationInterrupt(s);
}
}
protected void set(V v) {
if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {
outcome = v;
UNSAFE.putOrderedInt(this, stateOffset, NORMAL); // final state
finishCompletion();
}
}
//state为new是都可以设置
public boolean cancel(boolean mayInterruptIfRunning) {
//如果cancel时,state不是new,则返回cancel失败
if (state != NEW)
return false;
//由于线程切换
if (mayInterruptIfRunning) {
if (!UNSAFE.compareAndSwapInt(this, stateOffset, NEW, INTERRUPTING))
return false;
Thread t = runner;
if (t != null)
t.interrupt();
UNSAFE.putOrderedInt(this, stateOffset, INTERRUPTED); // final state
}
else if (!UNSAFE.compareAndSwapInt(this, stateOffset, NEW, CANCELLED))
return false;
finishCompletion();
return true;
}
runAndReset方法
周期性定时任务会使用此方法,执行任务,执行完后重新设置任务状态到初始状态
protected boolean runAndReset() {
if (state != NEW ||
!UNSAFE.compareAndSwapObject(this, runnerOffset,
null, Thread.currentThread())) //保证只有一个线程运行此任务
return false;
boolean ran = false;
int s = state;
try {
Callable<V> c = callable;
if (c != null && s == NEW) {
try {
c.call(); // don't set result
//不会设置state,一直保持NEW
ran = true;
} catch (Throwable ex) {
setException(ex);
}
}
} 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
s = state;
if (s >= INTERRUPTING)
handlePossibleCancellationInterrupt(s);
}
return ran && s == NEW;
}
总结
- FutureTask维护着一个WaitNode链表,每一个节点是一个被阻塞的线程。
- FutureTask包装着Runnable任务,执行完后,会将state设置为completing, 再变成Normal,最后唤醒所有等待线程
- 当任务为周期性定时任务时,运行runAndReset方法,state保持着NEW值