开发Android APP经常会使用AsyncTask框架来异步加载资源或者异步到服务器拉消息,等任务完成后再主动更新结果到UI主线程,AsyncTask框架可以非常方便的获取线程异步执行结果。Java 5之前,Java 并没有提供API用于查询线程是否执行完毕以及如何获取线程执行的结果;Java 5 之后版本提供的并发框架包java.util.concurrent对多线程提供了更多更好的支持,Future接口和FutureTask类是异步执行任务的框架的重要组成部分,为了更清楚的理解,我们还得从Runnable、Callable、ExecutorService等接口说起。

Runnable接口:instance可以使用new Thread(Runnable r)放到一个新线程中跑,没有返回结果;也可以使用ExecutorService.submit(Runnable r)放到线程池中跑,返回结果为null,等于没有返回结果,但可以通过返回的Future对象查询执行状态。

1
public abstract void run();

Callable接口:instance只能在ExecutorService的线程池中跑,但有返回结果,也可以通过返回的Future对象查询执行状态。表面上可以把Callable接口简单的理解为有返回结果的Runnalbe接口。

1
V call() throws Exception;

ExecutorService接口:线程池执行调度框架

1
2
3
4
5
<T> Future<T> submit(Callable<T> task);
<T> Future<T> submit(Runnable task, T result);
Future<?> submit(Runnable task);

Future接口:用于查询任务执行状态,获取执行结果,或者取消未执行的任务。在ExecutorService框架中,由于使用线程池,所以Runnable与Callable实例都当做任务看待,而不会当做“线程”看待,所以Future才有取消任务执行等接口。接口中的get()方法用于获取任务执行结果,因为任务是异步执行的,所以我们可以在需要使用结果的时候才调用get()方法,调用时如果任务还未执行完就会阻塞直到任务完成;当然我们也可以调用get的另一重载版本get(long timeout, TimeUnit unit),当阻塞时会等待指定的时间,如果时间到而任务还未完成,那么就会抛出TimeoutException。

1
2
3
4
5
6
7
8
9
10
    boolean cancel(boolean mayInterruptIfRunning);
    boolean isCancelled();
    boolean isDone();
    V get() throws InterruptedException, ExecutionException;
    V get(long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException;

FutureTask类:集Runnable、Callable、Future于一身,它首先实现了Runnable与Future接口,然后在构造函数中还要注入Callable对象(或者变形的Callable对象:Runnable + Result),所以FutureTask类既可以使用new Thread(Runnable r)放到一个新线程中跑,也可以使用ExecutorService.submit(Runnable r)放到线程池中跑,而且两种方式都可以获取返回结果,但实质是一样的,即如果要有返回结果那么构造函数一定要注入一个Callable对象,或者注入一个Runnable对象加一个预先给定的结果(个人觉得这作用不大)。

1
2
3
4
5
6
7
8
public interface RunnableFuture<V> extends Runnable, Future<V>{
...}
public class FutureTask<V> implements RunnableFuture<V> {
public FutureTask(Callable<V> callable)
public FutureTask(Runnable runnable, V result)
...
}

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package com.stevex.app.forkjoin;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
public class FutureTaskTest {
    public static void main(String[] args) {
        Callable<String> c = new Callable<String>() {
            public String call() {
                try {
                    TimeUnit.SECONDS.sleep(new Random().nextInt(5));
                catch (InterruptedException e) {
                    e.printStackTrace();
                }
                return "Callable--"+Thread.currentThread().getName();
            }
        };
        //seed a single thread
        FutureTask<String> ft1 = new FutureTask<String>(c);
        Thread t = new Thread(ft1);
        t.start();
        Runnable r = new Runnable() {
            public void run() {
                try {
                    TimeUnit.SECONDS.sleep(new Random().nextInt(5));
                catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        FutureTask<String> ft2 = new FutureTask<String>(r, "Runnable");//give return value directly
        FutureTask<String> ft3 = new FutureTask<String>(c);
        FutureTask<String> ft4 = new FutureTask<String>(c);
        FutureTask<String> ft5 = new FutureTask<String>(c);
        FutureTask<String> ft6 = new FutureTask<String>(c);
         
        ExecutorService es = Executors.newFixedThreadPool(2);//init ExecutorService
        es.submit(ft2);
        es.submit(ft3);
        es.submit(ft4);
        es.submit(ft5);
        es.submit(ft6);
         
         
         
        try {
            TimeUnit.SECONDS.sleep(1);
             
            if(ft1.isDone()){              
                ft4.cancel(false);
                 
                if(ft4.isCancelled()){
                    System.out.println("task4 cancelled.");
                }
            }
             
            if(ft2.isDone()){              
                ft5.cancel(false);
                 
                if(ft5.isCancelled()){
                    System.out.println("task5 cancelled.");
                }
            }
             
            if(ft3.isDone()){              
                ft6.cancel(false);
                 
                if(ft6.isCancelled()){
                    System.out.println("task5 cancelled.");
                }
            }
                             
            System.out.println("task1 retult:" + ft1.get());
            System.out.println("task2 retult:" + ft2.get());
            System.out.println("task3 retult:" + ft3.get());
             
            if(! ft4.isCancelled()){
                System.out.println("task4 retult:" + ft4.get());
            }
             
            if(! ft5.isCancelled()){
                System.out.println("task5 retult:" + ft5.get());
            }
             
            if(! ft6.isCancelled()){
                System.out.println("task6 retult:" + ft6.get());
            }  
             
            es.shutdown();//shut down ExecutorService
        catch (InterruptedException e) {
            e.printStackTrace();
        catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}

     本文转自sarchitect 51CTO博客,原文链接:http://blog.51cto.com/stevex/1576546,如需转载请自行联系原作者

Future和FutureTask实现异步计算相关推荐

  1. Android中Callable、Future、FutureTask的概念以及几种线程池的使用

    学习线程池必备知识: 在开始介绍线程池之前,先来介绍下Callable和Future的概念,众所周知,Android中实现多线程的方式有两种,实现Runnable接口或者继承一个Thread,但是这两 ...

  2. Future和FutureTask的区别

    先看下Future.FutureTask相关类的关系 Future只是一个接口,FutureTask是实现了RunnableFuture Future接口可以实现的功能 Future呈现的是异步计算的 ...

  3. future和futureTask 的区别

    future和futureTask 的区别: future 是一个接口,没有办法实例化,只能通过线程池的submit方法得到, 如上图所示,线程池执行submit方法可以得到返回值是Future< ...

  4. 13.FutureTask异步计算

    FutureTask 1.可取消的异步计算,FutureTask实现了Future的基本方法,提供了start.cancel 操作,可以查询计算是否完成,并且可以获取计算 的结果.结果只可以计算完成之 ...

  5. Java高并发编程:Callable、Future和FutureTask

    1. Callable 泛型接口,用于获取线程执行完的结果,Callable的声明如下 public interface Callable<V> {// 返回 V 类型的结果V call( ...

  6. 并发编程-21J.U.C组件拓展之Future和FutureTask

    文章目录 概述 FutureTask的三种运行状态 FutureTask的三种运行状态下的get/cancel操作及结果 FutureTask的实现 FutureTask的使用 示例 Future F ...

  7. Runnable、Callable、Executor、Future、FutureTask关系解读

    Future 介绍 Future表示异步计算的结果,它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的结果.Future的cancel方法可以取消任务的执行,它有一布尔参数,参数为 tru ...

  8. Callable、Future、FutureTask浅析

    1.Callable<V>接口 Runnable接口 public interface Runnable { public abstract void run(); } Callable ...

  9. 基于Callable和Future的匹配文件数量计算实例

    Runnable封装一个异步运行的任务:你可以把它想像成一个没有任何参数和返回值的异步方法.Callable和Runnable相似,但它有返回值.Callable接口是一个参数化的类型,只有一个方法c ...

最新文章

  1. 杨兴平离职完全是意料之中
  2. 绕了一圈,重回邗江区的怀抱
  3. python中的id()函数及读取list的例子
  4. Py之openpyxl:openpyxl库的简介、安装、使用方法之详细攻略
  5. php html_entity_decode 标签没有闭合,php – strip_tags和html_entity_decode组合无法按预期工作...
  6. Hadoop平台K-Means聚类算法分布式实现+MapReduce通俗讲解
  7. 移动端分步注册_移动应用程序的可用性测试:分步指南
  8. 人脸识别python face_recognize_python2.7使用face_recognition做人脸识别
  9. 《Spark GraphX in Action》书评及作者访谈
  10. PgSQL · 应用案例 · 聚集存储 与 BRIN索引
  11. 智能戒指,一个新鲜智能穿戴产物
  12. 软件基本功:不会代码共用,因为没有设计能力;代码共用都不会,谈什么设计
  13. 菜鸟的Java基础知识学习
  14. 天眼查 乱码 java_反爬虫解析-字体替换(天眼查/猫眼电影)
  15. 【现代密码学】作业一
  16. 2013-2015阿里双十一技术网络文章总结
  17. 因为一条SQL,我差点被祭天......,我太难了!
  18. 创业公司项目管理流程这样做才有效
  19. 高感性时代--全新思维:决胜未来的6大能力
  20. 南宁漏水检测:热烈祝贺广西中水荣获广西首届著名品牌

热门文章

  1. 文件服务器登入,密钥文件登录云服务器
  2. java中中的赋值运算符_Java中的赋值运算符
  3. php mysql orm_PHP ORM框架与简单代码实现(转)
  4. centos 计算器_Linux学习之CentOS(十五)--Linux常用命令之bc、man、shutdown...
  5. scrapy python下载图片_使用Scrapy自带的ImagesPipeline下载图片,并对其进行分类。
  6. 计算机考试可以带首饰吗,高考时不许考生戴框架眼镜?“无声考场”有新规,考生别忽视...
  7. 人工智能的炒作_人工智能与网络安全结合从炒作走向现实
  8. vue 属性 watch
  9. javascript Nested functions
  10. C语言 底层IO lseek