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

Future接口源码:

public interface Future<V> {
boolean cancel(boolean mayInterruptIfRunning);
boolean isCancelled();
boolean isDone();
V get() throws InterruptedException, ExecutionException;
V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
}

Future的demo

import java.util.ArrayList;
import java.util.List;
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.Future; public class Main {
public static void main(String[] args) {
ExecutorService executorService = Executors.newCachedThreadPool();
List<Future<String>> resultList = new ArrayList<Future<String>>(); // 创建10个任务并执行
for (int i = 0; i < 10; i++) {
// 使用ExecutorService执行Callable类型的任务,并将结果保存在future变量中
Future<String> future = executorService.submit(new TaskWithResult(i));
// 将任务执行结果存储到List中
resultList.add(future);
}
executorService.shutdown(); // 遍历任务的结果
for (Future<String> fs : resultList) {
try {
System.out.println(fs.get()); // 打印各个线程(任务)执行的结果
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
executorService.shutdownNow();
e.printStackTrace();
return;
}
}
}
}
class TaskWithResult implements Callable<String> {
private int id; public TaskWithResult(int id) {
this.id = id;
} /**
* 任务的具体过程,一旦任务传给ExecutorService的submit方法,则该方法自动在一个线程上执行。
*
* @return
* @throws Exception
*/
public String call() throws Exception {
System.out.println("call()方法被自动调用,干活!!! " + Thread.currentThread().getName());
if (new Random().nextBoolean())
throw new TaskException("Meet error in task." + Thread.currentThread().getName());
// 一个模拟耗时的操作
for (int i = 999999999; i > 0; i--)
;
return "call()方法被自动调用,任务的结果是:" + id + " " + Thread.currentThread().getName();
}
} class TaskException extends Exception {
public TaskException(String message) {
super(message);
}
}
call()方法被自动调用,干活!!!             pool-1-thread-2
call()方法被自动调用,干活!!! pool-1-thread-6
call()方法被自动调用,干活!!! pool-1-thread-1
call()方法被自动调用,任务的结果是:0 pool-1-thread-1
call()方法被自动调用,任务的结果是:1 pool-1-thread-2
call()方法被自动调用,干活!!! pool-1-thread-4
call()方法被自动调用,干活!!! pool-1-thread-9
call()方法被自动调用,干活!!! pool-1-thread-8
call()方法被自动调用,干活!!! pool-1-thread-10
call()方法被自动调用,干活!!! pool-1-thread-5
call()方法被自动调用,干活!!! pool-1-thread-3
call()方法被自动调用,干活!!! pool-1-thread-7
call()方法被自动调用,任务的结果是:2 pool-1-thread-3
call()方法被自动调用,任务的结果是:3 pool-1-thread-4
java.util.concurrent.ExecutionException: com.company.TaskException: Meet error in task.pool-1-thread-5
at java.util.concurrent.FutureTask.report(FutureTask.java:122)
at java.util.concurrent.FutureTask.get(FutureTask.java:192)
at com.company.Main.main(Main.java:29)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Caused by: com.company.TaskException: Meet error in task.pool-1-thread-5
at com.company.TaskWithResult.call(Main.java:56)
at com.company.TaskWithResult.call(Main.java:40)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)

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

Demo:

import java.util.Date;
import java.text.SimpleDateFormat;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask; public class Main {
public static void main(String[] args) {
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// 初始化一个Callable对象和FutureTask对象
Callable pAccount = new PrivateAccount();
FutureTask futureTask = new FutureTask(pAccount);
// 使用futureTask创建一个线程
Thread pAccountThread = new Thread(futureTask);
System.out.println("futureTask线程现在开始启动,启动时间为:" + df.format(new Date()));
pAccountThread.start();
System.out.println("futureTask线程开始执行其他任务");
// 从其他账户获取总金额
int totalMoney = new Random().nextInt(100000);
System.out.println("现在你在其他账户中的总金额为" + totalMoney);
System.out.println("等待私有账户总金额统计完毕...");
// 测试后台的计算线程是否完成,如果未完成则等待
while (!futureTask.isDone()) {
try {
Thread.sleep(500);
System.out.println("私有账户计算未完成继续等待...");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("futureTask线程计算完毕,此时时间为" + df.format(new Date()));
Integer privateAccountMoney = null;
try {
privateAccountMoney = (Integer) futureTask.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
System.out.println("您现在的总金额为:" + totalMoney +"||"+privateAccountMoney.intValue());
}
} class PrivateAccount implements Callable {
Integer totalMoney; @Override
public Object call() throws Exception {
Thread.sleep(5000);
totalMoney = new Integer(new Random().nextInt(10000));
System.out.println("您当前有" + totalMoney + "在您的私有账户中");
return totalMoney;
}
}
futureTask线程现在开始启动,启动时间为:2016-11-30 16:34:57
futureTask线程开始执行其他任务
现在你在其他账户中的总金额为17113
等待私有账户总金额统计完毕...
私有账户计算未完成继续等待...
私有账户计算未完成继续等待...
私有账户计算未完成继续等待...
私有账户计算未完成继续等待...
私有账户计算未完成继续等待...
私有账户计算未完成继续等待...
私有账户计算未完成继续等待...
私有账户计算未完成继续等待...
私有账户计算未完成继续等待...
您当前有8776在您的私有账户中
私有账户计算未完成继续等待...
futureTask线程计算完毕,此时时间为2016-11-30 16:35:02
您现在的总金额为:17113||8776

Demo2:

import java.util.Date;
import java.text.SimpleDateFormat;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask; public class Main {
public static void main(String[] args) {
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
FutureTask<String> futureTask=new FutureTask<>(new Callable<String>() {
//@Override
public String call() throws Exception {
// TODO Auto-generated method stub
return "回调完成";
}
});
Thread thread = new Thread(futureTask);
System.out.println("启动时间为:" + df.format(new Date()));
thread.start();
try {
String str=futureTask.get(); if(str.equals("回调完成"))
System.out.println("异步任务完成!");
else
System.out.println("Completed!");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
启动时间为:2016-12-01 09:37:03
异步任务完成!

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多线程Future模式

    Java多线程Future模式有些类似于Ajax的异步请求Future模式的核心在于:去除了主函数的等待时间,并使得原本需要等待的时间段可以用于处理其他业务逻辑 假设服务器的处理某个业务,该业务可以分 ...

  2. java中Future与FutureTask使用与分析

    Future与FutureTask都是用于获取线程执行的返回结果.下面我们就对两者之间的关系与使用进行一个大致的介绍与分析 一.Future与FutureTask介绍: Future位于java.ut ...

  3. JAVA 多线程 Callable 与 FutureTask:有返回值的多线程

    java多线程中,如果需要有返回值,就需要实现Callable接口. 看例子: 先建立一个Dowork这个类,就是平时某个业务的实现 package com.ming.thread.one; impo ...

  4. 【JAVA】java中Future、FutureTask的使用

    如今的系统基本都是分布式的,各个系统各司其职的,不可能一个系统干了全部系统的事. 所以系统之间的交互就越来越多了.那么系统之间的交互仅仅有通过网络来交互了,而网络必定会存在延时的情况. 比方A系统的一 ...

  5. Java 多线程 - Future

    Java中Future的使用场景和解析 https://blog.csdn.net/hongtaolong/article/details/83349705 (细看!!!)

  6. java多线程Future和Callable类的解释与使用

    一,描写叙述 ​在多线程下编程的时候.大家可能会遇到一种需求,就是我想在我开启的线程都结束时,同一时候获取每一个线程中返回的数据然后再做统一处理,在这种需求下,Future与Callable的组合就派 ...

  7. java 多线程 Future callable

    面向对象5大设计原则 1.单一职责原则  一个类只包含它相关的方法,增删改查.一个方法只包含单一的功能,增加.一个类最多包含10个方法,一个方法最多50行,一个类最多500行.重复的代码进行封装,Do ...

  8. Future和FutureTask的区别

    java中有Future和FutureTask这两个类 Future是一个接口,代表可以取消的任务,并可以获得任务的执行结果 FutureTask 是基本的实现了Future和runnable接口  ...

  9. paip.java 多线程参数以及返回值Future FutureTask 的使用.

    paip.java 多线程参数以及返回值Future FutureTask 的使用. 在并发编程时,一般使用runnable,然后扔给线程池完事,这种情况下不需要线程的结果. 所以run的返回值是vo ...

随机推荐

  1. 词频统计(WEB版)

    通过点击浏览按钮输入文件: 点击查询按钮后返回结果: 前台代码: <%@ Page Language="C#" AutoEventWireup="true" ...

  2. Ural 1741 Communication Fiend(隐式图+虚拟节点最短路)

    1741. Communication Fiend Time limit: 1.0 second Memory limit: 64 MB Kolya has returned from a summe ...

  3. optimize table table_name myisam mysql自动清除删除过留下的空记录

    optimize table table_name 这个可以清除你表里面的空记录,每次清除的时候记得锁表 lock tables table_name  write|read; unlock tabl ...

  4. java获取MySQL自动的int类型的Id

    @Resource(name = "dashboardTemplate") protected JdbcTemplate systemJDBCTemplate; //这个是Dao里 ...

  5. 如何用Apache POI操作Excel文件-----如何用Apache POI 画一个离散图

    有的时候,我们需要Excel中的数据,通过一个图画,可视化的表现出来. 那么这个时候,应该如何做呢?现在就借花献佛,以Apache POI自己提供的一个例子为例,给大家演示一下POI的API 如何画图 ...

  6. [办公应用]我的WORD文档表格操作不灵活 无法调整列宽

    最近同事的一个word文档中的表格操作非常不灵活,用鼠标直接调整列宽时总觉得很不灵活.她的操作系统为XP,office 为微软office 2003. 我首先检查了木马,检查了输入法等,结果都没有问题 ...

  7. 基于 jQuery Jcrop 插件的功能模块:头像剪裁

    /** Jcrop version: 0.9.12 jQuery version: 1.9.0 Author: 小dee Date: 2014.10.30 */ 先看看他山之石:博客园的头像模块也是使 ...

  8. 使用AndroidStudio自动生成JavaDoc文档

    选中所需要生成的Module,找到工具栏上的 Tools,选择 Generate JavaDoc 出现如图的窗口 选择输出路径,就自动生成. 如果出现编码错误提示,则在 Other command l ...

  9. mysql读写分离(PHP类)

    mysql读写分离(PHP类) 博客分类: php mysql   自己实现了php的读写分离,并且不用修改程序 优点:实现了读写分离,不依赖服务器硬件配置,并且都是可以配置read服务器,无限扩展 ...

  10. PHP CURL 多线程 GET/POST 类

    PHP CURL 多线程 GET/POST 类 2015-01-01 分类:技术文章 阅读(623) 评论(0) 如果有需要更正或更高效的建议,欢迎在OSchina分享~\(≧▽≦)/~ http:/ ...