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).今天我们通过一个小的案例 ...
随机推荐
- Java之基于S2SH与手机数据交互(一)
在前两篇博客,介绍了在eclipse上搭建SSH,可是好多小伙伴反映.看了偶写滴博客.跟着搭建还是错误百出,唉! 事实上不经历错误怎么能不见红线啊!于是我在上篇博客补充了他们的错误,还在被错误困扰的童 ...
- 【转载并整理】javaweb单点登录
很好的一篇,讲述原理的文章: http://www.importnew.com/22863.html https://www.cnblogs.com/Leo_wl/p/6111623.html 京东s ...
- 安卓listview滚动时背景变黑的解决方法
ListView是常用的显示控件,默认背景是和系统窗口一样的透明色,如果给ListView加上背景图片,或者背景颜色时,滚动时listView会黑掉, 原因是,滚动时,列表里面的view重绘时,用的依 ...
- python .dcm文件读取,并转化为.jpg格式
.dcm文件是DICOM(Digital Imaging and Communications in Medicine)即医学数字成像和通信中记录医学图像和相关信息的文件,在用于医学图像处理的时候我们 ...
- 怎么运行 ASP.NET Core控制台程序
aspnet test.dll
- Guid ToString 格式
转自 http://www.cnblogs.com/greenerycn/archive/2010/04/25/guid_tostring_format.html 在日常编程中,Guid是比较常用的, ...
- LED音乐频谱之输入数据处理
转载请注明出处:http://blog.csdn.net/ruoyunliufeng/article/details/38023431 通过前面的介绍我们知道.声音信号要通过AD转换,变成我们可以处理 ...
- mac安装GnuGP
1.首先查看gnugp最新的稳定版: localhost:~ jack$ brew search gnupg ==> Formulae gnupg gnupg-pkcs11-scd gnupg@ ...
- Go基础--终端操作和文件操作
终端操作 操作终端相关的文件句柄常量os.Stdin:标准输入os.Stdout:标准输出os.Stderr:标准错误输出 关于终端操作的代码例子: package main import " ...
- MySQL 自定义函数CREATE FUNCTION实例
分享一个MySQL 自定义函数CREATE FUNCTION的实例.mysql> delimiter $$mysql> CREATE FUNCTION myFunction-> (i ...