FutureTask 源码分析
FutureTask 源码分析,这个类的原理与我分析android当中的FutureTask类差不多[http://www.cnblogs.com/daxin/p/3802392.html]
public class FutureTask<V> implements RunnableFuture<V> {
/** 所有的方法全部委托sync */
private final Sync sync;
public FutureTask(Callable<V> callable) {
if (callable == null)
throw new NullPointerException();
sync = new Sync(callable);
}
public FutureTask(Runnable runnable, V result) {
sync = new Sync(Executors.callable(runnable, result));
}
public boolean isCancelled() {
return sync.innerIsCancelled();
}
public boolean isDone() {
return sync.innerIsDone();
}
public boolean cancel(boolean mayInterruptIfRunning) {
return sync.innerCancel(mayInterruptIfRunning);
}
public V get() throws InterruptedException, ExecutionException {
return sync.innerGet();
}
public V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException {
return sync.innerGet(unit.toNanos(timeout));
}
protected void done() { }
protected void set(V v) {
sync.innerSet(v);
}
protected void setException(Throwable t) {
sync.innerSetException(t);
}
public void run() {
sync.innerRun();
}
protected boolean runAndReset() {
return sync.innerRunAndReset();
}
private final class Sync extends AbstractQueuedSynchronizer {
private static final long serialVersionUID = -7828117401763700385L;
/** State value representing that task is ready to run */
/** 代表起始状态 */
private static final int READY = 0;
/** State value representing that task is running */
/** 代表正在运行中状态 */
private static final int RUNNING = 1;
/** State value representing that task ran */
/** 代表运行完成的状态 */
private static final int RAN = 2;
/** State value representing that task was cancelled */
/** 代表被取消的状态 */
private static final int CANCELLED = 4;
/** The underlying callable */
private final Callable<V> callable;
/** The result to return from get() */
private V result;
/** The exception to throw from get() */
private Throwable exception;
/**
* The thread running task. When nulled after set/cancel, this
* indicates that the results are accessible. Must be
* volatile, to ensure visibility upon completion.
*/
private volatile Thread runner;
Sync(Callable<V> callable) {
this.callable = callable;
}
/**
* 判断是否完成或者是否取消
* 传入0或者1 都返回0 说明任务没有完成 也没有取消
*/
private boolean ranOrCancelled(int state) {
return (state & (RAN | CANCELLED)) != 0;
}
/**
* AbstractQueuedSynchronizer的模板方法
* 返回1可以获取锁 返回-1说明获取锁失败
* 调用innerIsDone 返回TRUE 说明任务已经执行完毕
* 返回FALSE 说明任务没有执行完毕
*/
protected int tryAcquireShared(int ignore) {
return innerIsDone() ? 1 : -1;
}
/**
* 释放锁 将执行当前任务的线程设置为null
*/
protected boolean tryReleaseShared(int ignore) {
runner = null;
return true;
}
//判断任务是否被取消
boolean innerIsCancelled() {
return getState() == CANCELLED;
}
//判断任务是否完成(取消也算完成)
boolean innerIsDone() {
return ranOrCancelled(getState()) && runner == null;
}
//获取结果
V innerGet() throws InterruptedException, ExecutionException {
//首先调用AbstractQueuedSynchronizer的方法,这个方法会调用子类方法tryAcquireShared 上面有讲
//如果当前任务已经完成,那么当前线程可以向下运行,否则把当前线程加入队列阻塞.
acquireSharedInterruptibly(0);
//判断状态 如果取消了就抛CancellationException异常.
if (getState() == CANCELLED)
throw new CancellationException();
//如果任务执行过程中出现异常,这里包装一下抛出ExecutionException.
if (exception != null)
throw new ExecutionException(exception);
return result;
}
//获取结果
V innerGet(long nanosTimeout) throws InterruptedException, ExecutionException, TimeoutException {
//调用AbstractQueuedSynchronizer里的方法
// return tryAcquireShared(arg) >= 0 ||doAcquireSharedNanos(arg, nanosTimeout);
// 首先tryAcquireShared调用它获取锁,也就是看任务完事没,如果任务完事了就返回TRUE,那么执行逻辑同上。
// 如果获取不到锁,那么就阻塞当前线程给定的时间,如果时间到了再次任务还没完成则抛出异常。
if (!tryAcquireSharedNanos(0, nanosTimeout))
throw new TimeoutException();
if (getState() == CANCELLED)
throw new CancellationException();
if (exception != null)
throw new ExecutionException(exception);
return result;
}
void innerSet(V v) {
for (;;) {
int s = getState();
if (s == RAN)
return;
if (s == CANCELLED) {
// aggressively release to set runner to null,
// in case we are racing with a cancel request
// that will try to interrupt runner
releaseShared(0);
return;
}
//正常完成 设置状态为RAN
if (compareAndSetState(s, RAN)) {
result = v;
releaseShared(0);
done(); //通知子类
return;
}
}
}
void innerSetException(Throwable t) {
for (;;) {
int s = getState();
if (s == RAN)
return;
if (s == CANCELLED) {
// aggressively release to set runner to null,
// in case we are racing with a cancel request
// that will try to interrupt runner
releaseShared(0);
return;
}
//设置异常
if (compareAndSetState(s, RAN)) {
exception = t;
releaseShared(0);
done();//通知子类
return;
}
}
}
//取消任务
boolean innerCancel(boolean mayInterruptIfRunning) {
for (;;) {
int s = getState();
//如果任务已经结束,则返回FALSE
if (ranOrCancelled(s))
return false;
//设置任务的状态为CANCELLED
if (compareAndSetState(s, CANCELLED))
break;
}
//如果参数mayInterruptIfRunning=TRUE,那么设置线程的终端状态
if (mayInterruptIfRunning) {
Thread r = runner;
if (r != null)
r.interrupt();
}
//释放锁
releaseShared(0);
//调用子类方法,通知状态改变
done();
return true;
}
void innerRun() {
//如果任务不是初始状态则直接结束
if (!compareAndSetState(READY, RUNNING))
return;
runner = Thread.currentThread();
if (getState() == RUNNING) { // recheck after setting thread
V result;
try {
result = callable.call();
} catch (Throwable ex) {
//我们写的任务方法里如果出现异常则调用setException
setException(ex);
return;
}
//设置结果
set(result);
} else {
//释放锁
releaseShared(0); // cancel
}
}
boolean innerRunAndReset() {
if (!compareAndSetState(READY, RUNNING))
return false;
try {
runner = Thread.currentThread();
if (getState() == RUNNING)
callable.call(); // don't set result
runner = null;
return compareAndSetState(RUNNING, READY);
} catch (Throwable ex) {
setException(ex);
return false;
}
}
}
}
FutureTask 源码分析的更多相关文章
- Java并发编程笔记之FutureTask源码分析
FutureTask可用于异步获取执行结果或取消执行任务的场景.通过传入Runnable或者Callable的任务给FutureTask,直接调用其run方法或者放入线程池执行,之后可以在外部通过Fu ...
- 并发编程—— FutureTask 源码分析
1. 前言 当我们在 Java 中使用异步编程的时候,大部分时候,我们都会使用 Future,并且使用线程池的 submit 方法提交一个 Callable 对象.然后调用 Future 的 get ...
- FutureTask源码分析
1. 常量和变量 private volatile int state; // 任务状态 private static final int NEW = 0; private static final ...
- FutureTask源码分析(JDK7)
总览 A cancellable asynchronous computation. This class provides a base implementation of {@link Futur ...
- JUC源码分析-线程池篇(二)FutureTask
JUC源码分析-线程池篇(二)FutureTask JDK5 之后提供了 Callable 和 Future 接口,通过它们就可以在任务执行完毕之后得到任务的执行结果.本文从源代码角度分析下具体的实现 ...
- Java 多线程(五)—— 线程池基础 之 FutureTask源码解析
FutureTask是一个支持取消行为的异步任务执行器.该类实现了Future接口的方法. 如: 取消任务执行 查询任务是否执行完成 获取任务执行结果(”get“任务必须得执行完成才能获取结果,否则会 ...
- Java异步编程——深入源码分析FutureTask
Java的异步编程是一项非常常用的多线程技术. 之前通过源码详细分析了ThreadPoolExecutor<你真的懂ThreadPoolExecutor线程池技术吗?看了源码你会有全新的认识&g ...
- 线程之Callable、Future 和FutureTask使用及源码分析
一.Callable 我们知道启动线程有以下两种方式(jdk源码注释中官方定义只有两种启动方式,callable不算线程启动方式) 原文链接:http://www.studyshare.cn/blog ...
- android高级---->AsyncTask的源码分析
在Android中实现异步任务机制有两种方式,Handler和AsyncTask,它在子线程更新UI的例子可以参见我的博客(android基础---->子线程更新UI).今天我们通过一个小的案例 ...
随机推荐
- mysql 5.5数据库主从配置步骤详解
上次给大家介绍了mysql 5.1主从搭建配置教程,这次我们来实现mysql 5.5的主从复制,其实大体上配置是差不多的,只有点细微的差别. 系统:centos 5.x 需要的软件包:mysql-5. ...
- stm32定时器主从模式
TIM2作master:TIM3,TIM4作slave 定时器2事件更新被用作触发输出TRGO 从定时器TIM3,TIM4工作在从模式:门控模式 触发选择设为:ITR1,这样TIM2的TRGO就连到了 ...
- python 多进程,实际上都没有运行,sleep
进程以及状态 1. 进程程序:例如xxx.py这是程序,是一个静态的 进程:一个程序运行起来后,代码+用到的资源 称之为进程,它是操作系统分配资源的基本单元. 不仅可以通过线程完成多任务,进程也是可以 ...
- bash shell 合并多个文件内容到一个文件、查看多少行代码
一.简单版: $ cat **/* > merge.fuck 二.结合find + xargs + cat版本: $ find ./ -iregex '.*\.\(js\|scss\|tpl\) ...
- echarts 认知笔记
0.echarts.setOption的核心认知 请注意,它是合并对象,而不是替换对象. 举个简单的例子,如果你第一次setOption时在series中配置了10个对象. 那么你下一次你意图使用只有 ...
- Vivado SPI Flash程序下载
由于Vivado下载程序步骤和ISE有较大差异,特此写此文章,希望对大家有所帮助. 1,下载文件生成 在.bit文件生成后,在TCL中输入 write_cfgmem -format mcs -inte ...
- Hive怎样加入第三方JAR
以增加elsaticsearch-hadoop-2.1.2.jar为例,讲述在Hive中增加第三方jar的几种方式. 1,在hive shell中增加 [hadoop@hadoopcluster78 ...
- (原创)c++11中 function/lamda的链式调用
关于链式调用,比较典型的例子是c#中的linq,不过c#中的linq还只是一些特定函数的链式调用.c++中的链式调用更少见因为实现起来比较复杂.c++11支持了lamda和function,在一些延迟 ...
- Linux 守护进程
1.什么是守护进程 守护进程daemon指的是在后台运行的进程 2.前台任务和后台任务 前台任务:独占命令行窗口,运行完毕或手动终止,才能执行其他命令 以redis服务为例 redis-server ...
- (转)C++11里的智能指针
1. std::auto_ptr有些违背c++编程思想. 已经被"不建议使用了".2. 下文转自:http://blog.csdn.net/lanergaming/article/ ...