Future表示一个任务的周期,并提供了相应的方法来判断是否已经完成或者取消,以及获取任务的结果和取消任务。

Future接口源码:

  1. public interface Future<V> {
  2. boolean cancel(boolean mayInterruptIfRunning);
  3. boolean isCancelled();
  4. boolean isDone();
  5. V get() throws InterruptedException, ExecutionException;
  6. V get(long timeout, TimeUnit unit)
  7. throws InterruptedException, ExecutionException, TimeoutException;
  8. }

Future的demo

  1. import java.util.ArrayList;
  2. import java.util.List;
  3. import java.util.Random;
  4. import java.util.concurrent.Callable;
  5. import java.util.concurrent.ExecutionException;
  6. import java.util.concurrent.ExecutorService;
  7. import java.util.concurrent.Executors;
  8. import java.util.concurrent.Future;
  9.  
  10. public class Main {
  11. public static void main(String[] args) {
  12. ExecutorService executorService = Executors.newCachedThreadPool();
  13. List<Future<String>> resultList = new ArrayList<Future<String>>();
  14.  
  15. // 创建10个任务并执行
  16. for (int i = 0; i < 10; i++) {
  17. // 使用ExecutorService执行Callable类型的任务,并将结果保存在future变量中
  18. Future<String> future = executorService.submit(new TaskWithResult(i));
  19. // 将任务执行结果存储到List中
  20. resultList.add(future);
  21. }
  22. executorService.shutdown();
  23.  
  24. // 遍历任务的结果
  25. for (Future<String> fs : resultList) {
  26. try {
  27. System.out.println(fs.get()); // 打印各个线程(任务)执行的结果
  28. } catch (InterruptedException e) {
  29. e.printStackTrace();
  30. } catch (ExecutionException e) {
  31. executorService.shutdownNow();
  32. e.printStackTrace();
  33. return;
  34. }
  35. }
  36. }
  37. }
  38. class TaskWithResult implements Callable<String> {
  39. private int id;
  40.  
  41. public TaskWithResult(int id) {
  42. this.id = id;
  43. }
  44.  
  45. /**
  46. * 任务的具体过程,一旦任务传给ExecutorService的submit方法,则该方法自动在一个线程上执行。
  47. *
  48. * @return
  49. * @throws Exception
  50. */
  51. public String call() throws Exception {
  52. System.out.println("call()方法被自动调用,干活!!! " + Thread.currentThread().getName());
  53. if (new Random().nextBoolean())
  54. throw new TaskException("Meet error in task." + Thread.currentThread().getName());
  55. // 一个模拟耗时的操作
  56. for (int i = 999999999; i > 0; i--)
  57. ;
  58. return "call()方法被自动调用,任务的结果是:" + id + " " + Thread.currentThread().getName();
  59. }
  60. }
  61.  
  62. class TaskException extends Exception {
  63. public TaskException(String message) {
  64. super(message);
  65. }
  66. }
  1. call()方法被自动调用,干活!!! pool-1-thread-2
  2. call()方法被自动调用,干活!!! pool-1-thread-6
  3. call()方法被自动调用,干活!!! pool-1-thread-1
  4. call()方法被自动调用,任务的结果是:0 pool-1-thread-1
  5. call()方法被自动调用,任务的结果是:1 pool-1-thread-2
  6. call()方法被自动调用,干活!!! pool-1-thread-4
  7. call()方法被自动调用,干活!!! pool-1-thread-9
  8. call()方法被自动调用,干活!!! pool-1-thread-8
  9. call()方法被自动调用,干活!!! pool-1-thread-10
  10. call()方法被自动调用,干活!!! pool-1-thread-5
  11. call()方法被自动调用,干活!!! pool-1-thread-3
  12. call()方法被自动调用,干活!!! pool-1-thread-7
  13. call()方法被自动调用,任务的结果是:2 pool-1-thread-3
  14. call()方法被自动调用,任务的结果是:3 pool-1-thread-4
  15. java.util.concurrent.ExecutionException: com.company.TaskException: Meet error in task.pool-1-thread-5
  16. at java.util.concurrent.FutureTask.report(FutureTask.java:122)
  17. at java.util.concurrent.FutureTask.get(FutureTask.java:192)
  18. at com.company.Main.main(Main.java:29)
  19. at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  20. at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
  21. at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  22. at java.lang.reflect.Method.invoke(Method.java:498)
  23. at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
  24. Caused by: com.company.TaskException: Meet error in task.pool-1-thread-5
  25. at com.company.TaskWithResult.call(Main.java:56)
  26. at com.company.TaskWithResult.call(Main.java:40)
  27. at java.util.concurrent.FutureTask.run(FutureTask.java:266)
  28. at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
  29. at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
  30. at java.lang.Thread.run(Thread.java:745)

FutureTask是一个具体的实现类,ThreadPoolExecutor的submit方法返回的就是一个Future的实现,这个实现就是FutureTask的一个具体实例,FutureTask帮助实现了具体的任务执行,以及和Future接口中的get方法的关联。

Demo:

  1. import java.util.Date;
  2. import java.text.SimpleDateFormat;
  3. import java.util.Random;
  4. import java.util.concurrent.Callable;
  5. import java.util.concurrent.ExecutionException;
  6. import java.util.concurrent.FutureTask;
  7.  
  8. public class Main {
  9. public static void main(String[] args) {
  10. SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  11. // 初始化一个Callable对象和FutureTask对象
  12. Callable pAccount = new PrivateAccount();
  13. FutureTask futureTask = new FutureTask(pAccount);
  14. // 使用futureTask创建一个线程
  15. Thread pAccountThread = new Thread(futureTask);
  16. System.out.println("futureTask线程现在开始启动,启动时间为:" + df.format(new Date()));
  17. pAccountThread.start();
  18. System.out.println("futureTask线程开始执行其他任务");
  19. // 从其他账户获取总金额
  20. int totalMoney = new Random().nextInt(100000);
  21. System.out.println("现在你在其他账户中的总金额为" + totalMoney);
  22. System.out.println("等待私有账户总金额统计完毕...");
  23. // 测试后台的计算线程是否完成,如果未完成则等待
  24. while (!futureTask.isDone()) {
  25. try {
  26. Thread.sleep(500);
  27. System.out.println("私有账户计算未完成继续等待...");
  28. } catch (InterruptedException e) {
  29. e.printStackTrace();
  30. }
  31. }
  32. System.out.println("futureTask线程计算完毕,此时时间为" + df.format(new Date()));
  33. Integer privateAccountMoney = null;
  34. try {
  35. privateAccountMoney = (Integer) futureTask.get();
  36. } catch (InterruptedException e) {
  37. e.printStackTrace();
  38. } catch (ExecutionException e) {
  39. e.printStackTrace();
  40. }
  41. System.out.println("您现在的总金额为:" + totalMoney +"||"+privateAccountMoney.intValue());
  42. }
  43. }
  44.  
  45. class PrivateAccount implements Callable {
  46. Integer totalMoney;
  47.  
  48. @Override
  49. public Object call() throws Exception {
  50. Thread.sleep(5000);
  51. totalMoney = new Integer(new Random().nextInt(10000));
  52. System.out.println("您当前有" + totalMoney + "在您的私有账户中");
  53. return totalMoney;
  54. }
  55. }
  1. futureTask线程现在开始启动,启动时间为:2016-11-30 16:34:57
  2. futureTask线程开始执行其他任务
  3. 现在你在其他账户中的总金额为17113
  4. 等待私有账户总金额统计完毕...
  5. 私有账户计算未完成继续等待...
  6. 私有账户计算未完成继续等待...
  7. 私有账户计算未完成继续等待...
  8. 私有账户计算未完成继续等待...
  9. 私有账户计算未完成继续等待...
  10. 私有账户计算未完成继续等待...
  11. 私有账户计算未完成继续等待...
  12. 私有账户计算未完成继续等待...
  13. 私有账户计算未完成继续等待...
  14. 您当前有8776在您的私有账户中
  15. 私有账户计算未完成继续等待...
  16. futureTask线程计算完毕,此时时间为2016-11-30 16:35:02
  17. 您现在的总金额为:17113||8776

Demo2:

  1. import java.util.Date;
  2. import java.text.SimpleDateFormat;
  3. import java.util.concurrent.Callable;
  4. import java.util.concurrent.ExecutionException;
  5. import java.util.concurrent.FutureTask;
  6.  
  7. public class Main {
  8. public static void main(String[] args) {
  9. SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  10. FutureTask<String> futureTask=new FutureTask<>(new Callable<String>() {
  11. //@Override
  12. public String call() throws Exception {
  13. // TODO Auto-generated method stub
  14. return "回调完成";
  15. }
  16. });
  17. Thread thread = new Thread(futureTask);
  18. System.out.println("启动时间为:" + df.format(new Date()));
  19. thread.start();
  20. try {
  21. String str=futureTask.get();
  22.  
  23. if(str.equals("回调完成"))
  24. System.out.println("异步任务完成!");
  25. else
  26. System.out.println("Completed!");
  27. } catch (InterruptedException e) {
  28. // TODO Auto-generated catch block
  29. e.printStackTrace();
  30. } catch (ExecutionException e) {
  31. // TODO Auto-generated catch block
  32. e.printStackTrace();
  33. }
  34. }
  35. }
  1. 启动时间为:2016-12-01 09:37:03
  2. 异步任务完成!

http://ifeve.com/futuretask-source/

http://www.liuinsect.com/2014/02/17/futuretask-%E6%BA%90%E7%A0%81%E8%A7%A3%E6%9E%90/

http://blog.csdn.net/ghsau/article/details/7451464

http://blog.csdn.net/javazejian/article/details/50896505

Java 线程池Future和FutureTask的更多相关文章

  1. Java线程池(Callable+Future模式)

    转: Java线程池(Callable+Future模式) Java线程池(Callable+Future模式) Java通过Executors提供四种线程池 1)newCachedThreadPoo ...

  2. Java线程池详解

    一.线程池初探 所谓线程池,就是将多个线程放在一个池子里面(所谓池化技术),然后需要线程的时候不是创建一个线程,而是从线程池里面获取一个可用的线程,然后执行我们的任务.线程池的关键在于它为我们管理了多 ...

  3. 这么说吧,java线程池的实现原理其实很简单

    好处 : 线程是稀缺资源,如果被无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,合理的使用线程池对线程进行统一分配.调优和监控,有以下好处: 1.降低资源消耗: 2.提高响应速度: 3.提高线 ...

  4. java线程池技术(二): 核心ThreadPoolExecutor介绍

    版权声明:本文出自汪磊的博客,转载请务必注明出处. Java线程池技术属于比较"古老"而又比较基础的技术了,本篇博客主要作用是个人技术梳理,没什么新玩意. 一.Java线程池技术的 ...

  5. 并发编程(十二)—— Java 线程池 实现原理与源码深度解析 之 submit 方法 (二)

    在上一篇<并发编程(十一)—— Java 线程池 实现原理与源码深度解析(一)>中提到了线程池ThreadPoolExecutor的原理以及它的execute方法.这篇文章是接着上一篇文章 ...

  6. 并发编程(十一)—— Java 线程池 实现原理与源码深度解析(一)

    史上最清晰的线程池源码分析 鼎鼎大名的线程池.不需要多说!!!!! 这篇博客深入分析 Java 中线程池的实现. 总览 下图是 java 线程池几个相关类的继承结构:    先简单说说这个继承结构,E ...

  7. Java线程池 Executor框架概述

    线程池的意义 循环利用线程资源,避免重复创建和销毁线程 线程池的任务是异步执行的,只要提交完成就能快速返回,可以提高应用响应性 Java线程池还有一个很重要的意义:Java线程池就是JDK 5 推出的 ...

  8. java线程池和中断总结

    目录 java线程池和中断总结 一. 线程池的使用 二. java中断机制 中断的处理 三. 线程间通信机制总结 java线程池和中断总结 本系列文是对自己学习多线程和平时使用过程中的知识梳理,不适合 ...

  9. 深入分析java线程池的实现原理(转载)

    前言 线程是稀缺资源,如果被无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,合理的使用线程池对线程进行统一分配.调优和监控,有以下好处: 1.降低资源消耗: 2.提高响应速度: 3.提高线程的 ...

随机推荐

  1. 2017 Multi-University Training Contest - Team 7

    HDU6121 Build a tree 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6121 题目意思:一棵 n 个点的完全 k 叉树,结点标号从 ...

  2. setMasksToBounds

    setMasksToBounds 在IB中,当你使用Custom类型的Button时,你可以指定按钮的背景色.但当你运行时按钮就失去了圆角特性,你看到的仅仅是一个方块.因为custombutton没有 ...

  3. 1.引入jQuery

    http://libs.baidu.com/jquery/2.1.4/jquery.js

  4. 自己开发Thinkpad电源管理程序

    自己开发Thinkpad电源管理程序 - 知乎 https://zhuanlan.zhihu.com/p/20706403

  5. The Personal Touch Client Identification 个性化接触 客户识别

    w服务器要知道和谁在交谈. HTTP The Definitive Guide Web servers may talk to thousands of different clients simul ...

  6. 荣誉墙项目day26 django 项目路由配置

    项目路由配置文件包括:配置目录里的urls.py文件和各个app目录里的urls.py文件 1.include()——从项目主路由分配到各APP主路由 from django.conf.urls im ...

  7. Python在运维工作中的经典应用之ansible

    1.安装ansible wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo curl -o /e ...

  8. Android Volley全然解析(四),带你从源代码的角度理解Volley

    版权声明:本文出自郭霖的博客,转载必须注明出处. https://blog.csdn.net/sinyu890807/article/details/17656437 转载请注明出处:http://b ...

  9. 001-linux scp文件拷贝

    scp是secure copy的简写,用于在Linux下进行远程拷贝文件的命令,和它类似的命令有cp,不过cp只是在本机进行拷贝不能跨服务器,而且scp传输是加密的.可能会稍微影响一下速度.当你服务器 ...

  10. ReSharper Ultimate 2017 下载地址及破解方法

    https://download.jetbrains.8686c.com/resharper/JetBrains.ReSharperUltimate.2017.1.2.exe 安装完成后,打开vs   ...