package cn.liu.thread;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
/**
* https://blog.csdn.net/imxutao/article/details/79672337
* @author Dick
*
*/
public class Demo3 implements Callable<String>{
private int total = 20;
@Override
public String call() throws Exception {
while(total>0) {
System.out.println(Thread.currentThread().getName()+": "+total);
total--;
}
return "no tatal";
}
public static void main(String[] args) throws InterruptedException, ExecutionException {
FutureTask<String> thread = new FutureTask<>(new Demo3());
new Thread(thread,"one").start();
new Thread(thread,"two").start();
System.out.println(thread.get());
}
}
在我的预期当执行结果应该是one和two交替执行。但是却不是。
但是Runnable却这样可以
package cn.liu.thread;
public class Demo2 implements Runnable{
private int i = 20;
@Override
public void run() {
while(i>0) {
System.out.println(Thread.currentThread().getName()+i);
i--;
}
}
public static void main(String[] args) {
Demo2 t = new Demo2();
//把t对象交给Thread来创建一个线程
new Thread(t,"one").start();
new Thread(t,"two").start();
}
}
public class FutureTask<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;
@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);
}
public FutureTask(Callable<V> callable) {
if (callable == null)
throw new NullPointerException();
this.callable = callable;
this.state = NEW; // ensure visibility of callable
}
public boolean isCancelled() {
return state >= CANCELLED;
}
public boolean isDone() {
return state != NEW;
}
protected void set(V v) {
if (STATE.compareAndSet(this, NEW, COMPLETING)) {
outcome = v;
STATE.setRelease(this, NORMAL); // final state
finishCompletion();
}
}
public void run() {
if (state != NEW ||
!RUNNER.compareAndSet(this, 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;
if (s >= INTERRUPTING)
handlePossibleCancellationInterrupt(s);
}
}
private static final VarHandle STATE;
private static final VarHandle RUNNER;
private static final VarHandle WAITERS;
static {
try {
MethodHandles.Lookup l = MethodHandles.lookup();
STATE = l.findVarHandle(FutureTask.class, "state", int.class);
RUNNER = l.findVarHandle(FutureTask.class, "runner", Thread.class);
WAITERS = l.findVarHandle(FutureTask.class, "waiters", WaitNode.class);
} catch (ReflectiveOperationException e) {
throw new ExceptionInInitializerError(e);
}
// Reduce the risk of rare disastrous classloading in first call to
// LockSupport.park: https://bugs.openjdk.java.net/browse/JDK-8074773
Class<?> ensureLoaded = LockSupport.class;
}
}
我们直接看run()方法,里面有一个状态state, if (state != NEW ||
!RUNNER.compareAndSet(this, null, Thread.currentThread()))
return;
不满足此条件会直接return,不会执行run方法。
我们的示例代码:
FutureTask<String> thread = new FutureTask<>(new Demo3());//初始化,state=NEW;
new Thread(thread,"one").start();//此时执行此线程,会进入FutureTask的run方法,执行,然后stata会被改变
/*
第二次同一个对象,进入FutureTask的run方法,因state被改变,直接ruturn。这样设计主要是为了 线程安全
*/
new Thread(thread,"two").start();