一、代码
public static void main(String[] args) throws Exception {
Callable<String> call = new Callable<String>() {
@Override
public String call() throws Exception {
System.out.println("要花3秒时间去做的其他事");
Thread.sleep(3000);
System.out.println("已经做完了其他事");
return "洗车";
}
};
FutureTask<String> task = new FutureTask<>(call);
Thread thread = new Thread(task);
thread.start();
// do something
System.out.println("做的第一件事");
String result = task.get();
System.out.println("要做的其他事:" + result);
}
}
1.分析
二、UML图
三、代码分析
这张图我们看到状态,那么我就先把状态说明下
看代码前,说明下几个重要的变量
- private volatile Thread runner:当前运行的线程
- private Object outcome:输出的内容
- private volatile WaitNode waiters:等待的节点
-
static final class WaitNode { volatile Thread thread;//线程 volatile WaitNode next;//下一个节点 WaitNode() { thread = Thread.currentThread(); }//当前线程加入节点 }
-
继续看代码
run方法
异常方法
finishCompletion
set方法
handlePossibleCancellationInterrupt
因为我们代码有调用task,get()方法,接下来我们看看get的源码
s = awaitDone(false, 0L);
removeWaiter(q);
private void removeWaiter(WaitNode node) {
if (node != null) {
//设置节点的线程为空,做删除标记
node.thread = null;
retry:
for (;;) { // restart on removeWaiter race
for (WaitNode pred = null, q = waiters, s; q != null; q = s) {
s = q.next;
//thread不为空,continue
if (q.thread != null)
pred = q;
//thread为空且pred不为空
else if (pred != null) {
//删除q
pred.next = s;
//检查一下pred的thread,如果被其他线程修改,retry outer loop
if (pred.thread == null) // check for race
continue retry;
}
//thread为空且pred为空说明q为栈顶,将q.next设置为栈顶,失败则retry
else if (!UNSAFE.compareAndSwapObject(this, waitersOffset,
q, s))
continue retry;
}
break;
}
}
}
流程
1. 当节点进来,先让节点的线程设置为空,表示该节点已经删除了(该节点一定在waiters的链上)
2. 获取当前的节点q,
3 设置s为q的后继节点
4 如果当q节点的线程不是空(说明传过来的节点node 不是当前节点),设置pred变量表示q
5 q=s,q节点指向下一个节点。开始第二轮的for循环
6 设置s为q的后继节点(这个时候q为指针向前的节点),如果q的线程是空,说明该节点已经标记删除了
7 看q节点的前面节点pred是否为空,不为空,那么就删除q节点。如果前面节点的线程为空(标记删除),则前面节点也要被删除,说明跳转retry重新来;如果前面节点pred为空,说明q节点是栈顶,尝试将q的后继点击设置为栈顶(栈顶多线程竞争栈顶,所以失败就重来),失败就重新来过。
8一直遍历节点,直到节点遍历完(这个删除节点可以删除多个哦)
parkNanos(Object blocker, long nanos)
park(Object blocker)
report(s)
源码已经看完了,现在来对源码总体了解下,他是做什么?
四,如果接下来的代码还看不懂,建议还是改行吧,哈哈
public class Demo3 {
public static void main(String[] args) throws Exception {
System.out.println("main---: 当前线程是:" + Thread.currentThread());
Callable<String> call = new Callable<String>() {
@Override
public String call() throws Exception {
System.out.println("main---: 异步线程开启,当前线程是:" + Thread.currentThread());
Thread.sleep(2000);
// if(1==1){
// throw new RuntimeException("异常");
// }
return "洗车";
}
};
FutureTask3<String> task1 = new FutureTask3<>(call);
Runnable Runnable=new Runnable(){
@Override
public void run() {
Thread thread = new Thread(task1);
thread.setName("01");
thread.start();
try {
System.out.println("main---run: 异步线程返回值:" + task1.get());
} catch (ExecutionException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
Thread thread1 = new Thread(Runnable);
thread1.setName("异步线程1");
thread1.start();
Thread thread2 = new Thread(Runnable);
thread2.setName("异步线程2");
thread2.start();
Thread thread3 = new Thread(Runnable);
thread3.setName("异步线程3");
thread3.start();
}
}
----------------
package com.roocon.demo;
import sun.misc.Unsafe;
import java.lang.reflect.Field;
import java.util.concurrent.*;
import java.util.concurrent.locks.LockSupport;
public class FutureTask3<V> implements RunnableFuture<V> {
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;
private Callable<V> callable;
private Object outcome;
private volatile Thread runner;
private volatile WaitNode waiters;//内存可见
public FutureTask3(Callable<V> callable) {
// 初始化callable
this.callable = callable;
}
//状态变化
// NEW-->COMPLETING-->NORMAL
// NEW-->COMPLETING-->EXCEPTIONAL
// NEW-->CANCELLED
// NEW-->INTERRUPTING-->INTERRUPTED
public void run() {
//排除其他情况,只对new状态执行run方法
//如果状态不是初始化或更新runner线程为主线程不成功,不执行run方法。
System.out.println("run---: 当前线程是:" + Thread.currentThread());
if (state != NEW || !UNSAFE.compareAndSwapObject(this, runnerOffset, null, Thread.currentThread())) {
System.out.println("! run ");
return;
}
try {
Callable<V> c = callable;//多线问题
//只有new 才执行
if (state == NEW && c != null) {
System.out.println("run---:state == NEW");
V result;
boolean isSucess;//是否正常执行
try {
System.out.println("run---:执行call");
result = c.call();
isSucess = true;
} catch (Throwable e) {//call方法异常
result = null;
isSucess = false;
System.out.println("run---:setException");
setException(e);
}
if (isSucess) {
System.out.println("run---:执行set");
set(result);
}
}
} finally {
}
}
/**
* @return void
* @Author feizhou
* @Description 状态 NEW ---:COMPLETING
* @Date 下午 11:37 2019/10/30 0030
* @Param [result]
**/
private void set(V result) {
//完成就等待状态变为>COMPLETING
//为了防止状态一直是COMPLETING,所以当状态是COMPLETING的时候,需要立马变更为>COMPLETING状态
try {
Thread.sleep(2000);//等待waitDone阻塞线程,卡住set方法
System.out.println("set---:-等待waitDone阻塞线程,卡住set方法,当前线程是:" + Thread.currentThread());
} catch (InterruptedException e) {
e.printStackTrace();
}
if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {
outcome = result;
UNSAFE.putOrderedInt(this, stateOffset, NORMAL);
//唤醒线程
System.out.println("set---:-finishCompletion");
finishCompletion();
}
}
/**
* @return void
* @Author feizhou
* @Description 异常处理
* @Date 上午 12:34 2019/10/30 0030
* @Param []
**/
private void setException(Throwable e) {
System.out.println("setExpression---:当前线程是:" + Thread.currentThread());
if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {
outcome = e;
UNSAFE.putOrderedInt(this, stateOffset, EXCEPTIONAL);
//唤醒线程
System.out.println("setExpression---:finishCompletion");
finishCompletion();
}
}
/**
* @return void
* @Author feizhou
* @Description 结束, 唤醒线程
* @Date 上午 12:37 2019/10/30 0030
* @Param []
**/
private void finishCompletion() {
for (WaitNode q; (q = waiters) != null; ) {//唤醒所有的线程
System.out.println("finishCompletion---:遍历每一个节点,唤醒每一个节点的线程");
if (UNSAFE.compareAndSwapObject(this, waitersOffset, q, null)) {//当节点设置为空
for (; ; ) {
Thread t = q.thread;
System.out.println("finishCompletion---:当前节点是:" + q);
if (t != null) {//删除当前节点
System.out.println("finishCompletion---:唤醒被阻塞的线程:" + t);
q.thread = null;
//唤醒线程
LockSupport.unpark(t);
}
WaitNode next = q.next;
if (next == null) {//最后一个节点就跳出
System.out.println("finishCompletion---:最后一个节点就跳出finishCompletion方法");
break;
}
q.next = null;//断开节点连接
q = next;
System.out.println("finishCompletion---:断开q与下一个节点的连接,设置q为下一个节点");
}
//如果执行到这里,就跳出外面的for循环
break;
}
}
callable = null;
}
@Override
public V get() throws ExecutionException, InterruptedException {
System.out.println("get---: 当前线程是:" + Thread.currentThread());
int s = state;
if (s <= COMPLETING) {//还在执行中
//阻塞当前进程
System.out.println("get---: 执行awaitDone");
s=awaitDone();
}
return report(s);
}
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);
}
//新增等待节点
private int awaitDone() {
WaitNode q = null;
boolean queue = false;
for (; ; ) {
int s = state;
System.out.println("awaitDone---:状态:" + s);
if (s > COMPLETING) {
System.out.println("awaitDone---:s > COMPLETING");
if (q != null) {完成或者异常或者中断,就返回
q.thread = null;
return s;
}
} else if (s == COMPLETING) {
System.out.println("awaitDone---:s == COMPLETING");
//完成就等待状态变为>COMPLETING
//为了防止状态一直是COMPLETING,所以当状态是COMPLETING的时候,需要立马变更为>COMPLETING状态,set有这样的操作
Thread.yield();
} else if (q == null) {
System.out.println("awaitDone---:q == null");
q = new WaitNode();
} else if (!queue) {//直到加入节点尾部成功。
queue = UNSAFE.compareAndSwapObject(this, waitersOffset, q.next = waiters, q);
System.out.println("awaitDone---:waiters=" + waiters + ",queue:" + queue);
} else {//状态是state1<COMPLETING
//阻塞当前线程
System.out.println("awaitDone---:阻塞当前线程是:" + Thread.currentThread());
LockSupport.park(this);
}
}
}
@Override
public boolean cancel(boolean mayInterruptIfRunning) {
return false;
}
@Override
public boolean isCancelled() {
return false;
}
@Override
public boolean isDone() {
return false;
}
@Override
public V get(long timeout, TimeUnit unit) throws ExecutionException {
return (V) outcome;
}
static final class WaitNode {
//主线程(阻塞主线程)
volatile Thread thread;
volatile WaitNode next;
WaitNode() {
//主线程
thread = Thread.currentThread();
}
@Override
public String toString() {
return "WaitNode{" +
"thread=" + thread +
", next=" + next +
'}';
}
}
// Unsafe mechanics
private static sun.misc.Unsafe UNSAFE;
private static final long stateOffset;
private static final long runnerOffset;
private static final long waitersOffset;
static {
try {
Field unsafeField = Unsafe.class.getDeclaredFields()[0];
unsafeField.setAccessible(true);
try {
UNSAFE = (Unsafe) unsafeField.get(null);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
Class<?> k = FutureTask.class;
stateOffset = UNSAFE.objectFieldOffset
(k.getDeclaredField("state"));
runnerOffset = UNSAFE.objectFieldOffset
(k.getDeclaredField("runner"));
waitersOffset = UNSAFE.objectFieldOffset
(k.getDeclaredField("waiters"));
} catch (Exception e) {
throw new Error(e);
}
}
@Override
public String toString() {
return "FutureTask3{" +
"state=" + state +
", callable=" + callable +
", outcome=" + outcome +
", runner=" + runner +
", waiters=" + waiters +
'}';
}
}
------------
测试输出:
main---: 当前线程是:Thread[main,5,main]
get---: 当前线程是:Thread[异步线程2,5,main]
get---: 执行awaitDone
awaitDone---:状态:0
awaitDone---:q == null
run---: 当前线程是:Thread[01,5,main]
run---:state == NEW
run---:执行call
main---: 异步线程开启,当前线程是:Thread[01,5,main]
get---: 当前线程是:Thread[异步线程3,5,main]
get---: 执行awaitDone
awaitDone---:状态:0
awaitDone---:q == null
get---: 当前线程是:Thread[异步线程1,5,main]
get---: 执行awaitDone
awaitDone---:状态:0
awaitDone---:q == null
awaitDone---:状态:0
awaitDone---:状态:0
awaitDone---:waiters=WaitNode{thread=Thread[异步线程2,5,main], next=null},queue:true
awaitDone---:状态:0
awaitDone---:阻塞当前线程是:Thread[异步线程2,5,main]
awaitDone---:waiters=WaitNode{thread=Thread[异步线程1,5,main], next=WaitNode{thread=Thread[异步线程2,5,main], next=null}},queue:true
awaitDone---:状态:0
awaitDone---:阻塞当前线程是:Thread[异步线程1,5,main]
run---: 当前线程是:Thread[01,5,main]
! run
awaitDone---:状态:0
awaitDone---:waiters=WaitNode{thread=Thread[异步线程3,5,main], next=WaitNode{thread=Thread[异步线程1,5,main], next=WaitNode{thread=Thread[异步线程2,5,main], next=null}}},queue:true
awaitDone---:状态:0
awaitDone---:阻塞当前线程是:Thread[异步线程3,5,main]
run---: 当前线程是:Thread[01,5,main]
! run
run---:执行set
set---:-等待waitDone阻塞线程,卡住set方法,当前线程是:Thread[01,5,main]
set---:-finishCompletion
finishCompletion---:遍历每一个节点,唤醒每一个节点的线程
finishCompletion---:当前节点是:WaitNode{thread=Thread[异步线程3,5,main], next=WaitNode{thread=Thread[异步线程1,5,main], next=WaitNode{thread=Thread[异步线程2,5,main], next=null}}}
finishCompletion---:唤醒被阻塞的线程:Thread[异步线程3,5,main]
finishCompletion---:断开q与下一个节点的连接,设置q为下一个节点
finishCompletion---:当前节点是:WaitNode{thread=Thread[异步线程1,5,main], next=WaitNode{thread=Thread[异步线程2,5,main], next=null}}
finishCompletion---:唤醒被阻塞的线程:Thread[异步线程1,5,main]
finishCompletion---:断开q与下一个节点的连接,设置q为下一个节点
finishCompletion---:当前节点是:WaitNode{thread=Thread[异步线程2,5,main], next=null}
finishCompletion---:唤醒被阻塞的线程:Thread[异步线程2,5,main]
awaitDone---:状态:2
awaitDone---:s > COMPLETING
main---run: 异步线程返回值:洗车
awaitDone---:状态:2
awaitDone---:s > COMPLETING
main---run: 异步线程返回值:洗车
awaitDone---:状态:2
awaitDone---:s > COMPLETING
main---run: 异步线程返回值:洗车
finishCompletion---:最后一个节点就跳出finishCompletion方法
Process finished with exit code 0