尊敬原创作者,转载请注明出处:

http://blog.csdn.net/gemmem/article/details/8956703

FutureTask是为了弥补Thread的不足而设计的,它可以让程序员准确地知道线程什么时候执行完成并获得到线程执行完成后返回的结果(如果有需要)。

java.util.concurrent 
类 FutureTask<V>

java.lang.Object
  

java.util.concurrent.FutureTask<V>
类型参数:
V - 此 FutureTask 的 get 方法所返回的结果类型。
所有已实现的接口:
RunnableFuture<V>, RunnableFuture<V>

public class FutureTask<V>extends Objectimplements RunnableFuture<V>

可取消的异步计算。利用开始和取消计算的方法、查询计算是否完成的方法和获取计算结果的方法,此类提供了对Future 的基本实现。仅在计算完成时才能获取结果;如果计算尚未完成,则阻塞 get 方法。一旦计算完成,就不能再重新开始或取消计算。

可使用 FutureTask 包装 Callable 或Runnable 对象。因为FutureTask 实现了Runnable,所以可将FutureTask 提交给 Executor 执行。

除了作为一个独立的类外,此类还提供了 protected 功能,这在创建自定义任务类时可能很有用。

这个解释过于全面,没有突出重点,其实重点就在于FutureTask的get()方法。

先看一个demo:

package base2;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import java.util.concurrent.Callable; public class Concurrent_FutureTask {
/**
* @param args
*/
public static void main(String[] args) {
MyCall task1 = new MyCall("this is task1");
MyCall.Result result = new MyCall.Result();
result.setFlag("this is result");
ExecutorService pool = Executors.newFixedThreadPool(3);
Future<MyCall.Result> f1 = new FutureTask<MyCall.Result>(task1) {
@Override
protected void done() {
try { MyCall.Result r = (MyCall.Result) get(); System.out.println(r.getFlag() + " about callable");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
super.done();
} };
Future<MyCall.Result> f2 = new FutureTask<MyCall.Result>(new MyRun(),result){
@Override
protected void done() {
try { MyCall.Result r = (MyCall.Result) get(); System.out.println(r.getFlag() + " about runnable");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
super.done();
}
};
pool.execute((Runnable) f1);
pool.execute((Runnable) f2);
} } class MyCall implements Callable {
Result r;
String j = "";
MyCall() { } MyCall(String flag) {
j = flag;
}
@Override
public Result call() throws Exception {
System.out.println("this is MyCall call");
r = new Result();
r.setFlag(j);
return r;
} public static class Result {
private String flag = ""; public String getFlag() {
return flag;
} public void setFlag(String flag) {
this.flag = flag;
}
}
} class MyRun implements Runnable{ @Override
public void run() {
System.out.println("this is MyRun run"); } }
 

对代码做如下分析:

pool.execute((Runnable) f1)执行后,会创建一个线程,并执行MyCall的call方法,call方法执行完毕后,f1 实例的done()立即执行,这时候f1实例的get()方法会返回之前call()方法返回的Result实例。

pool.execute((Runnable) f2)的执行和f1类似,不同的是其中done()中的get()返回的实例是f2构造函数提供的。

Java FutureTask理解的更多相关文章

  1. [java] 深入理解内部类: inner-classes

    [java] 深入理解内部类: inner-classes // */ // ]]>   [java] 深入理解内部类: inner-classes Table of Contents 1 简介 ...

  2. Java初始化理解与总结 转载

    Java的初始化可以分为两个部分: (a)类的初始化 (b)对象的创建 一.类的初始化 1.1 概念介绍: 一个类(class)要被使用必须经过装载,连接,初始化这样的过程. 在装载阶段,类装载器会把 ...

  3. 从Java视角理解CPU上下文切换(Context Switch)

    从Java视角理解系统结构连载, 关注我的微博(链接)了解最新动态   在高性能编程时,经常接触到多线程. 起初我们的理解是, 多个线程并行地执行总比单个线程要快, 就像多个人一起干活总比一个人干要快 ...

  4. 从Java视角理解CPU缓存(CPU Cache)

    从Java视角理解系统结构连载, 关注我的微博(链接)了解最新动态众所周知, CPU是计算机的大脑, 它负责执行程序的指令; 内存负责存数据, 包括程序自身数据. 同样大家都知道, 内存比CPU慢很多 ...

  5. Java IO 理解流的概念

    Java IO 理解流的概念 @author ixenos 在理解流时首先理解以下概念 1.流的来源和去向一般在构造器指出 2.方法中的形参一般是将流输出到某个位置,读取(INPUT)流从流读出数据( ...

  6. Effective Java通俗理解(持续更新)

    这篇博客是Java经典书籍<Effective Java(第二版)>的读书笔记,此书共有78条关于编写高质量Java代码的建议,我会试着逐一对其进行更为通俗易懂地讲解,故此篇博客的更新大约 ...

  7. Effective Java通俗理解(下)

    Effective Java通俗理解(上) 第31条:用实例域代替序数 枚举类型有一个ordinal方法,它范围该常量的序数从0开始,不建议使用这个方法,因为这不能很好地对枚举进行维护,正确应该是利用 ...

  8. JAVA个人理解

    为了找到别人写的好文章,先分享下自己的知识,找找感觉路线. 学java前接触的c,后来转向java.第一个照面理解的就是面向对象,没想到让我想了好多年.当时有个负责任的老师说面向对象这个词具体释义众说 ...

  9. Effective Java通俗理解(上)

    这篇博客是Java经典书籍<Effective Java(第二版)>的读书笔记,此书共有78条关于编写高质量Java代码的建议,我会试着逐一对其进行更为通俗易懂地讲解,故此篇博客的更新大约 ...

随机推荐

  1. java命名规则

    java变量命名是不能以#开头的.Java变量的命名规则如下:$ .字母.下划线开头都行,不能以数字开头 后面的可以是数字.字母.下划线, 其他的命名方式,都会报错,且不能运行. 以字母.下划线( _ ...

  2. html语言中的meta元素

    1.定义语言  格式:〈meta http-equiv=″Content-Type″ content=″text/html; charset=gb2312″〉  这是META最常见的用法,在制作网页时 ...

  3. javascript-设置div隐藏

    html code: <div class="title"> <ul id="col02_left_title"> <li> ...

  4. java_设计模式_状态模式_State Pattern(2016-08-16)

    定义: 当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类. 类图: 状态模式所涉及到的角色有: ● 环境(Context)角色,也成上下文:定义客户端所感兴趣的接口,同时维护一个 ...

  5. gray code 格雷码 递归

    格雷码 the n-1 bit code, with 0 prepended to each word, followd by the n-1 bit code in reverse order, w ...

  6. 输出第N个素数

    输出第N个素数 public class FindNthPrime { public static void main(String[] args){ int N = Integer.parseInt ...

  7. iframe中的各种跳转方法(转)

    一.背景A,B,C,D都是jsp,D是C的iframe,C是B的iframe,B是A的iframe,在D中跳转页面的写法区别如下. 二.JS跳转window.location.href.locatio ...

  8. c#配置文件appStrings配置节的读取、添加和修改

    程序开发中经常会用到应用程序配置文件,好处就是维护人员可以直接修改配置文件进行维护,而不用修改程序.好,切入主题. 给项目添加应用程序配置文件App.config,先在里面写几句: <?xml ...

  9. jquery 核心

    1.jquery核心函数    1.1 jQuery([selector,[context]]);        $("#id"),$(document.body),$(" ...

  10. http知识累积

    1. http头 Host, Host请求报头域主要用于指定被请求资源的Internet主机和端口号,它通常从HTTP URL中提取出来的. 如果有黑客劫持了用户的请求,篡改了Host的内容,当请求到 ...