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).今天我们通过一个小的案例 ...
随机推荐
- C++项目參考解答:求Fibonacci数列
[项目:求Fibonacci数列] Fibonacci数列在计算科学.经济学等领域中广泛使用,其特点是:第一.二个数是1,从第3个数開始,每一个数是其前两个数之和.据此,这个数列为:1 1 2 3 5 ...
- springboot 错误处理
在 java web开发过程中,难免会有一些系统异常或人为产生一些异常.在 RESTful springboot 项目中如何优雅的处理? 分析:在RESTful 风格的springboot 项目中,返 ...
- Node.js中,获取req请求的原始IP
Node.js代码 var express = require('express'); var app = express(); var http = require('http'); var ser ...
- 使用NPOI 转换Excel TO HTML (导出格式不如原生Excel好看)
//HSSFWorkbook workbook = ExcelToHtmlUtils.LoadXls(strPath); //ExcelToHtmlConverter excelToHtmlConve ...
- 使用curator 来管理elasticsearch的index
这里我们参考官网安装curator https://www.cookiesinn.org/elasticsearch_curator_delete_indices/ https://www.elast ...
- js省市级联实现
js省市级联实现. for [element] in [collection] 用于循环下标,常用于json for(index in arr){ console.info("下标:&quo ...
- [svc]linux性能监控
参考 w - Show who is logged on and what they are doing. [root@n1 ~]# w # w - Show who is logged on and ...
- DBeaver利用方式简介
当攻击者能够进入内网,同时发现某台服务器装有弱口令的数据库时,除了在console中查看数据库信息外, 还可以利用第三方工具进行数据库读取,本例中使用DBeaver进行查看. 1. 下载DBeaver ...
- [Windows Azure] .NET Multi-Tier Application Using Storage Tables, Queues, and Blobs - 1 of 5
.NET Multi-Tier Application Using Storage Tables, Queues, and Blobs - 1 of 5 This tutorial series sh ...
- 【DMQ引擎】-DMQ多进程插件引擎服务平台介绍
写过服务端项目的程序员可能都有非常痛苦的经历,服务端经常奔溃,无从查起.的确一个服务端要稳定下来要经过长期的积累,不停的测试,调试,发现问题,解决问题.这个周期可能很长,几个月,甚至以年计算.许多企业 ...