文章目录
一、Future
简介
Future
表示一个任务的生命周期,并提供了相应的方法来判断是否已经完成或取消,以及获取任务的结果和取消任务等。
对应方法图:
(1)创建Future
方法
-
将一个
Runnable
或Callable
提交到Executor
-
显示地为某个指定的
Runnable
或Callable
实例化一个FutureTask
二、FutureTask
仿写
(1)定义 MyFutureTask
public class MyFutureTask<V> implements Future<V>,Runnable {
private Callable<V> callable;
private boolean running = false;
private boolean done = false;
private boolean cancel = false;
private ReentrantLock lock ;
private V outcome;
MyFutureTask(Callable<V> callable) {
if(callable == null) {
throw new NullPointerException("callable cannot be null!");
}
this.callable = callable;
this.done = false;
this.lock = new ReentrantLock();
}
@Override
public boolean cancel(boolean mayInterruptIfRunning) {
callable = null;
cancel = true;
return true;
}
@Override
public boolean isCancelled() {
return cancel;
}
@Override
public boolean isDone() {
return done;
}
@Override
public V get() {
try {
// 这里需要判断任务是否完成
// 若没完成,则阻塞
// 若完成,则返回
this.lock.lock();
return outcome;
}finally{
this.lock.unlock();
}
}
@Override
public V get(long timeout, TimeUnit unit) {
try {
this.lock.tryLock(timeout, unit);
return outcome;
}catch (InterruptedException e) {
return null;
}finally{
this.lock.unlock();
}
}
@Override
public void run() {
try {
this.lock.lock();
running = true;
try {
outcome = callable.call();
} catch (Exception e) {
e.printStackTrace();
}
done = true;
running = false;
}finally {
this.lock.unlock();
}
}
}
(2)测试
public class Test {
public static void main(String[] args) {
Test test = new Test();
Future<String> future = test.search("yyf");
try {
System.out.println("result : " + future.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
public Future<String> search(String prodName) {
MyFutureTask<String> future = new MyFutureTask<String>(new Callable<String>() {
@Override
public String call() {
try {
System.out.println(String.format("searching %s",prodName));
Thread.sleep(3000);
return "hha";
}catch(InterruptedException e){
System.out.println("search function is Interrupted!");
}
return null;
}
});
new Thread(future).start();// 或提交到线程池
return future;
}
}
可能会出现输出结果不一致的情况。
原因:主线程和子线程并发运行,尝试获得lock
三、FutureTask
源码分析
(1)方法图
(2)get()
public V get() throws InterruptedException, ExecutionException {
// 获取运行状态
int s = state;
// 如果是 NEW 或 COMPLETING,则等待
if (s <= COMPLETING)
s = awaitDone(false, 0L);
// 返回
return report(s);
}
// awaitDone(false, 0L);
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;
// 状态为 NOMAL 或 EXCEPTIONAL 或 CANCELLED 或 INTERRUPTING 或 INTERRUPTED
if (s > COMPLETING) {
if (q != null)
q.thread = null;
return s;
}
// 任务完成状态为 NOMAL,COMPLETING 是 代表可能还在运行中
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);
}
}
可见,想要跳出自旋:
- 状态变更
- 过期
// 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);
}
(3)run()
public void run() {
// 状态不是新建 或者 置换当前节点失效
if (state != NEW ||
!UNSAFE.compareAndSwapObject(this, runnerOffset,
null, Thread.currentThread()))
return;
try {
Callable<V> c = callable;
// 运行不为null 且 状态为新建
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);
}
}
// setException(ex);
protected void setException(Throwable t) {
if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {
outcome = t;
UNSAFE.putOrderedInt(this, stateOffset, EXCEPTIONAL); // final state
finishCompletion();
}
}
// finishCompletion()
// 逐个取出等待节点,进行唤醒
private void finishCompletion() {
// assert state > COMPLETING;
for (WaitNode q; (q = waiters) != null;) {
if (UNSAFE.compareAndSwapObject(this, waitersOffset, q, null)) {
for (;;) {
Thread t = q.thread;
if (t != null) {
q.thread = null;
LockSupport.unpark(t);
}
WaitNode next = q.next;
if (next == null)
break;
q.next = null; // unlink to help gc
q = next;
}
break;
}
}
done();
callable = null; // to reduce footprint
}