文章目录
1.参数说明
1.任务状态
1.新创建状态:NEW
private static final int NEW = 0;
2.完成中但还没完成:COMPLETING
private static final int COMPLETING = 1;
3.正常状态:NORMAL
private static final int NORMAL = 2;
4.异常状态:EXCEPTIONAL
private static final int EXCEPTIONAL = 3;
5.取消状态:CANCELLED
private static final int CANCELLED = 4;
6.中断中状态:INTERRUPTING
private static final int INTERRUPTING = 5;
7.已经中断状态:INTERRUPTED
private static final int INTERRUPTED = 6;
8.状态切换
参照给出的注释得到下面状态切换的几种情况:
/**
* Possible state transitions:
* NEW -> COMPLETING -> NORMAL
* NEW -> COMPLETING -> EXCEPTIONAL
* NEW -> CANCELLED
* NEW -> INTERRUPTING -> INTERRUPTED
*/
2.等待的节点:WaiterNode
可以看到注释这边说的是使用Treiber Stack的方式来实现,即无锁并发栈,他的基本思想也是通过CAS,后面我们会看到,这边先了解一下这个数据结构,WaitNode,记录对应的等待线程和下一个等待的节点.
在FutureTask中维护了一个WaiterNode即private volatile WaitNode waiters;
这边的waiter其实对应的就是FutureTask的get操作,因为任务可能还没处理完, get得不到结果,可能多次get,所以需要对这些get操作进行阻塞,等待真正的任务处理结束之后,再回到队列中去处理get的操作
/**
* Simple linked list nodes to record waiting threads in a Treiber
* stack. See other classes such as Phaser and SynchronousQueue
* for more detailed explanation.
*/
static final class WaitNode {
volatile Thread thread;
volatile WaitNode next;
WaitNode() {
thread = Thread.currentThread(); }
}
3.返回结果或者返回异常:outcome
后面我们会具体说到这个,这边先了解一下,可以设置返回结果(在构造函数中设置),如果一切正常的话,按照设置的结果返回,如果发生异常则会被设置为对应的异常实例。
outcome在本地可以说算是一个缓存,当任务运行过程中,如果调用get方法,会一直等待任务结束,然后返回outcome的结果,像我们刚才说的两种情况
1.一切正常返回构造时设置的结果
2.发生异常则返回对应异常实例
/** The result to return or exception to throw from get() */
private Object outcome; // non-volatile, protected by state reads/writes
4.任务回调接口:Callable
/**
* A task that returns a result and may throw an exception.
* Implementors define a single method with no arguments called
**/
/** The underlying callable; nulled out after running */
private Callable<V> callable;
5.任务线程:runner
/** The thread running the callable; CASed during run() */
private volatile Thread runner;
2.构造函数
1.Callable入参
通过传入Callable的实现类来构造FutureTask
public FutureTask(Callable<V> callable) {
if (callable == null){
throw new NullPointerException();
}
this.callable = callable;
this.state = NEW; // ensure visibility of callable