【多线程研究专题三】【FutureTask与Callable的本质】
来源:互联网 发布:mac 微软雅黑字体关了 编辑:程序博客网 时间:2024/06/15 09:58
吐槽:以前看了好多文章和书籍讲FutureTask,讲的很细,但不得要领,还是会忘。绝知此事要躬行,还是得自己亲自分析下源码。
1、FutureTask本质上是Runnable和Callable的实现类,就是一个任务类,主函数也是run()。
2、FutureTask实现了异步任务,怎么实现的?是因为Callable?
不是。Callable.call()与Runnable.run()只是一个很普通的方法,是同步方法。异步方法是因为FutureTask的实现机制,使用了Guard Suspension模式。
下面说下Guard Suspension模式的核心思想,以及Future是如何实现的:
GS模式作用:把同步方法,变为异步方法。
GS模式思想:线程A执行与一般同步方法无异,主要是线程B(异步任务,如FutureTask所在的线程)的执行不一样:异步任务的get()方法调用wait()方法进入wait状态(java有多种实现),等待同步方法call()执行结束(在线程B中运行),通知get方法取消wait状态。这就是GS的主要思想。
示意图如下:
![](file:///C:/Users/20140624/AppData/Local/Temp/enhtmlclip/Image.png)
从上图可见,run()和get()是主要角色,run的代码如下:
set()其实很简单,就是返回outcome结果,并调用finishCompletion(),通知get()方法,取消wait状态。
![](file:///C:/Users/20140624/AppData/Local/Temp/enhtmlclip/Image(1).png)
![](file:///C:/Users/20140624/AppData/Local/Temp/enhtmlclip/Image(2).png)
再看下get(),awaitDone()就是进入了wait()状态。其实现是一个for(;;)循环。对应上面的finishCompletion(),我们只需要关注思想,先不管具体实现。
反正awatiDone()的无限循环会被finishCompletion()打破。然后调用report()
publicVget()throwsInterruptedException, ExecutionException {
ints=state;
if(s<=COMPLETING)
s= awaitDone(false, 0L);
returnreport(s);
}
report()实现如下。就是把set()里面设置的outcome传给x,然后返回。
@SuppressWarnings("unchecked")
privateVreport(ints)throwsExecutionException {
Objectx=outcome;
if(s==NORMAL)
return(V)x;
if(s>=CANCELLED)
thrownewCancellationException();
thrownewExecutionException((Throwable)x);
}
小结:
1. FutureTask的核心思想是:通过awaitDone()和finishCompletion()实现异步操作。
2. 第1点,被封装为get()/set()。其中get()被外部线程A调用,set()被线程B--FutureTask的run()调用。
3.Callable的call()本质上是同步方法。
4.FutureTask的主函数只运行callable方法,Runnable.run()是通过一个adapter转为Callable的()。
public FutureTask(Runnable runnable, V result) {
this.callable = Executors.callable(runnable, result);
this.state = NEW; // ensure visibility of callable
}
this.callable = Executors.callable(runnable, result);
this.state = NEW; // ensure visibility of callable
}
Executors.callable定义如下:
public static <T> Callable<T> callable(Runnable task, T result) {
if (task == null)
throw new NullPointerException();
return new RunnableAdapter<T>(task, result);
}
if (task == null)
throw new NullPointerException();
return new RunnableAdapter<T>(task, result);
}
0 0
- 【多线程研究专题三】【FutureTask与Callable的本质】
- Callable 与 FutureTask:有返回值的多线程
- JAVA 笔记 Callable 与 FutureTask:有返回值的多线程
- 多线程任务Callable与Future或FutureTask的使用
- 多线程编程之Callable 与 FutureTask
- 多线程--callable、Future、FutureTask
- 理解Android多线程里面三种任务Runnable和Callable和FutureTask的用法
- Java多线程研究06-带返回值的线程定义接口Callable以及Future,FutureTask的使用
- JAVA---多线程之Callable与Future,FutureTask,及其简单应用
- Java多线程 Callable Future FutureTask
- 【Java多线程】-Callable,Future,FutureTask
- 多线程之 Callable Future FutureTask
- Java多线程研究(七)Callable与Future的应用
- 有返回值的多线程的实现:FutureTask+Callable
- callable结合FutureTask的多线程使用(免打扰模式)
- callable结合FutureTask的多线程使用(免打扰模式)
- callable结合FutureTask的多线程使用(免打扰模式)
- 多线程下的其它组件之CyclicBarrier、Callable、Future、FutureTask
- Java入门学习-深入理解集合
- Codeforces 804D
- shell连接linux失败问题
- Jersey2xjersey-media-multipart+Jetty实现文件上传下载
- HTML5实现音频和视频嵌入
- 【多线程研究专题三】【FutureTask与Callable的本质】
- Linux常用命令(2)(欢迎指正,持续更新)
- Predict the Winner
- 日期格式DateFormat使用
- sed命令入门及进阶
- dot-files/directories 点开头的文件或文件夹(windows/linux)
- Visual Studio Code 常用快捷键
- MST
- java导出百万级数据到excel解决方案