「这是我参与11月更文挑战的第19天,活动详情查看:2021最后一次更文挑战」
状态转换
state表示状态,由CAS操作保证原子性.提供了其中状态
public FutureTask(Callable<V> callable) {
if (callable == null)
throw new NullPointerException();
this.callable = callable;
this.state = NEW; // ensure visibility of callable
}
💡 当任务即将完成/完成,state设置成COMPLETING/NORMAL
当任务执行正常结束前,会通过CAS将其设置成COMPLETING,代表即将完成.随后就会变RMAL或者EXCEPTIONAL.
// run方法中在call()结束后,将其作为参数传入set方法
protected void set(V v) {
//将执行状态变更为COMPLETING
if (UNSAFE.compareAndSwapint(this, stateOffset, NEW, COMPLETING)) {
//设置执行结果
outcome = v;
//设置执行状态为NORMAL
UNSAFE.putOrderedint(this, stateOffset, NORMAL);
// final state
//执行完成后处理操作,具体就是遍历阻塞链表,删除链表节点,并唤醒每个节点关联的线程
finishCompletion();
}
}
任务正常执行 : NEW→COMPLETING→NORMAL
执行中出现异常 : NEW→COMPLETING→EXCEPTIONAL
任务执行过程中被取消,并且不响应中断 : NEW→CANCELLED
任务执行过程中被取消,并响应中断 : NEW→INTERRUPTING→INTERRUPTED
线程执行过程
💡 run()方法1.判断当前任务状态和runner是否准备就绪.
2.double-check判断任务状态
3.开始执行业务逻辑,调用call方法
4.如果业务异常,调用setException方法
public void run() {
// 判断当前状态是否为NEW,或者当前线程是否已经切换成功
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 {
// 重置线程
runner = null;
int s = state;
// 线程执行出现中断,释放当前线程占用 Thread.yield()
if (s >= INTERRUPTING)
handlePossibleCancellationInterrupt(s);
}
}
💡 setException
1.将state的状态改变成COMPLETING,将异常对象赋给outcome,然后再将状态变成EXCEPTIONAL.最后作结束工作.
2.outcome变量存储的是执行结果或者异常对象,用于返回结果
3.通过CAS对线程状态进行更新
protected void setException(Throwable t) {
if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {
outcome = t;
UNSAFE.putOrderedInt(this, stateOffset, EXCEPTIONAL); // final state
finishCompletion();
}
}