这段时间在公司实习都没时间总结所学的知识,接下来尽量每天一篇输出
----关于FutureTask,最初是在狂刷面试题的时候遇见的,初见觉得十分的陌生,最简单的理解就是,FutureTask是用来接收具有返回值的线程的结果的,具有返回结果的线程的实现方法是Callable()或者是Callable()封装的Runnable(),随着学习,逐渐深入发现没那么简单,感觉读源码,当过了那个令人及其恶心的门槛的时候,真的会沉醉其中
----先贴一张不规范的类图,连接一下其中源码中类和接口之间的关系
----Future状态迁移图
----从图中可以看出FutureTask实现了RunableFuture接口,而RunableFuture接口实现了Runable和Future接口,所以FutureTask可以交给Excutor执行,除此之外还可以在线程中调用FutureTask.run()方法运行。
//用FutureTask包装Runnable或者Callable对象
FutureTask<String> future = new FutureTask<String>(new Callable<String>() {
@Override
public String call() {
});
第一种情况把FutureTask交给Executor或submit执行
ExecutorService threadPool = Executors.newFixedThreadPool(10);
Future<String> future = threadPool.submit(task);
第二种情况在线程中运行Future
ExecutorService threadPool = Executors.newFixedThreadPool(10);
CreatThreadDemo4 demo4 = new CreatThreadDemo4();
//最终实现的是runable接口
FutureTask<Integer> task = new FutureTask<Integer>(demo4);
Thread thread = new Thread(task);
thread.start();
/***********也可以直接run*************/
future.run();
----FutureTask的实现
FutureTask的实现是基于AQS(抽象同步队列)的,每一个基于AQS实现的同步器都会包含两种类型的操作,至少一个acquire操作,这个操作阻塞调用线程,除非直到AQS允许这个线程继续执行,至少一个release操作,这个操作改变AQS状态,这个状态可以允许一个或多个阻塞线程接触阻塞,FutureTask中的方法run()或者cancle()扮演者这个角色
FutureTask的acquire操作由get方法完成
/**
* @throws CancellationException {@inheritDoc}
*/
public V get() throws InterruptedException, ExecutionException {
int s = state;
if (s <= COMPLETING)
s = awaitDone(false, 0L);
return report(s);
}
/**
* @throws CancellationException {@inheritDoc}
*/
public V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException {
if (unit == null)
throw new NullPointerException();
int s = state;
if (s <= COMPLETING &&
(s = awaitDone(true, unit.toNanos(timeout))) <= COMPLETING)
throw new TimeoutException();
return report(s);
}
FutureTask中的run()和cancle()
public void run() {
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 must be non-null until state is settled to
// prevent concurrent calls to run()
runner = null;
// state must be re-read after nulling runner to prevent
// leaked interrupts
int s = state;
if (s >= INTERRUPTING)
handlePossibleCancellationInterrupt(s);
}
}
public boolean cancel(boolean mayInterruptIfRunning) {
if (!(state == NEW &&
UNSAFE.compareAndSwapInt(this, stateOffset, NEW,
mayInterruptIfRunning ? INTERRUPTING : CANCELLED)))
return false;
try { // in case call to interrupt throws exception
if (mayInterruptIfRunning) {
try {
Thread t = runner;
if (t != null)
t.interrupt();
} finally { // final state
UNSAFE.putOrderedInt(this, stateOffset, INTERRUPTED);
}
}
} finally {
finishCompletion();
}
return true;
}
----在jdk1.7中,基于复合优于继承的原则,FutureTask声明了一个内部私有类Sync继承了AQS,这个内部类只需要实现状态检查和状态更
新的方法,这些方法将控制FutureTask的获取和释放操作。通过内部继承AQS的一个私有类Sync来实现操作代理的;Sync 实现了AQS
的tryAcquireShared()和tryReleaseShared()方法
FutureTask代的get()方法代理到AQS的acquireSharedInterruptibly()方法上
FutureTask的run()和cancel()方法代理到AQS的release()方法上
其中源码介绍见https://www.jianshu.com/p/385df6faf585
----在jdk1.8中运用了另一种方法
介绍见https://www.jianshu.com/p/d0be341748de