之前接触过Future模式,是在业务处理费时费力时出现的一种解决方案,可是一直没有时间深入了解其实现方式,今天从FutureTask开始来研究具体实现。
首先我写了一个demo
public class FutureTaskDemo {
public static void main(String[] args) throws Exception {
Callable
主要三部分
比较容易理解,其实我们还要理解一下callable和runable的一些关联,我个人认为callable是runable的升级版,runable接口的run方法是不提供返回值的,所以有一定的局限性,callable接口中的call方法能够提供返回值。
FutureTask实现了RunnableFuture接口
而RunnableFuture extends Runnable, Future
所以我们可以说FutureTask是一个Future对象
因为FutureTask实现了Runnable接口,所以我们可以分析一下run方法,看看FutureTask的运行机制到底是怎么样的
public void run() {
if (state != NEW ||
!UNSAFE.compareAndSwapObject(this, runnerOffset,
null, Thread.currentThread()))
return;
try {
Callable 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);
}
}
这个时候我们可以看到有意思的一个事情就是state,也就是状态,那状态总共分为几类呢,我们可以看一下源码
/**
* The run state of this task, initially NEW. The run state
* transitions to a terminal state only in methods set,
* setException, and cancel. During completion, state may take on
* transient values of COMPLETING (while outcome is being set) or
* INTERRUPTING (only while interrupting the runner to satisfy a
* cancel(true)). Transitions from these intermediate to final
* states use cheaper ordered/lazy writes because values are unique
* and cannot be further modified.
*
* 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;
我们可以看到总共有7种状态,而且源码处给出了4种状态转换的情况
那怎么样就能判断业务处理完成了呢,也就是callable执行完成了
我们分析一下
public boolean isDone() {
return state != NEW;
}
可以看到,只要不是new状态,就是已完成。
我们这个时候就可以断定
run方法里面有一个boolean类型的ran字段,当callable对象执行完成call方法后,ran置为true,如果ran为true,则set。那么set的是什么呢,我们可以断定,set的就是状态(state)
相关源码
/**
* Sets the result of this future to the given value unless
* this future has already been set or has been cancelled.
*
* This method is invoked internally by the {@link #run} method
* upon successful completion of the computation.
*
* @param v the value
*/
protected void set(V v) {
if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {
outcome = v;
UNSAFE.putOrderedInt(this, stateOffset, NORMAL); // final state
finishCompletion();
}
}
这里面有个compareAndSwapInt方法调用,比较并操作,也就是CAS,要改变state,那么,改变了状态,我们就可以知道是不是已经完成了(isDone)毕竟isDone是根据状态来判断的。
get方法的源码
/**
* @throws CancellationException {@inheritDoc}
*/
public V get() throws InterruptedException, ExecutionException {
int s = state;
if (s <= COMPLETING)
s = awaitDone(false, 0L);
return report(s);
}
如果没有完成那么就等待线程完成
/**
* Awaits completion or aborts on interrupt or timeout.
*
* @param timed true if use timed waits
* @param nanos time to wait, if timed
* @return state upon completion
*/
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;
}
else if (s == COMPLETING) // cannot time out yet
Thread.yield();
else if (q == null)
q = new WaitNode();
else if (!queued)
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);
}
}
知道等到状态不为new 返回继续执行report方法。
/**
* Returns result or throws exception for completed task.
*
* @param s completed state value
*/
@SuppressWarnings("unchecked")
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);
}
把实际的处理结果返回出去,get操作完成,当然也有可能被取消或者被中断了,那么抛异常出来。
就简单分析到这吧