简述

FutureTask是Future接口的实现类,并提供了可取消的异步处理的功能,它包含了启动和取消(start and cancel)任务的方法,同时也包含了可以返回FutureTask状态(completed or cancelled)的方法。我们可以自定义一个Future任务,然后使用线程池执行器Java Thread Pool Executor 去异步执行任务。

FutureTask

从类图中可以看出,FutureTask实现了接口RunnableFuture,接口RunnableFuture又继承了Runnable和Future接口,所以它既可以作为Runnable被线程执行,又可以作为Future得到Callable的结果,因此FutureTask提供了两个构造方法:

  1. public FutureTask(Callable<V> callable)
  2. public FutureTask(Runnable runnable, V result)

使用事例

1.使用Callable+Future获取执行结果

  1. package com.lkf.mulithread;
  2. import java.util.concurrent.*;
  3. public class CallableFutureExample {
  4. public static void main(String[] args) {
  5. //创建线程池
  6. ExecutorService executor = Executors.newCachedThreadPool();
  7. //实例化任务
  8. MyTask task = new MyTask();
  9. //提交任务
  10. Future<Integer> result = executor.submit(task);
  11. //关闭线程池
  12. executor.shutdown();
  13. try {
  14. Thread.sleep(1000);
  15. } catch (InterruptedException e1) {
  16. e1.printStackTrace();
  17. }
  18. System.out.println("主线程在执行任务");
  19. try {
  20. System.out.println("MyTask的返回值:"+result.get());
  21. } catch (InterruptedException e) {
  22. e.printStackTrace();
  23. } catch (ExecutionException e) {
  24. e.printStackTrace();
  25. }
  26. System.out.println("所有任务执行完毕");
  27. }
  28. static class MyTask implements Callable<Integer> {
  29. @Override
  30. public Integer call() throws Exception {
  31. System.out.println("子线程正在执行");
  32. Thread.sleep(5000);
  33. return 1000;
  34. }
  35. }
  36. }

2.使用Callable+FutureTask获取执行结果

  1. package com.lkf.mulithread;
  2. import java.util.concurrent.*;
  3. public class FutureTaskExample {
  4. public static class MyCallable implements Callable<String> {
  5. private long waitTime;
  6. public MyCallable(int timeInMillis){
  7. this.waitTime=timeInMillis;
  8. }
  9. @Override
  10. public String call() throws Exception {
  11. Thread.sleep(waitTime);
  12. //返回当前线程的名字
  13. return Thread.currentThread().getName();
  14. }
  15. }
  16. public static void main(String[] args) {
  17. MyCallable callable1 = new MyCallable(1000);
  18. MyCallable callable2 = new MyCallable(2000);
  19. FutureTask<String> futureTask1 = new FutureTask<String>(callable1);
  20. FutureTask<String> futureTask2 = new FutureTask<String>(callable2);
  21. ExecutorService executor = Executors.newFixedThreadPool(2);
  22. executor.execute(futureTask1);
  23. executor.execute(futureTask2);
  24. while (true) {
  25. try {
  26. if(futureTask1.isDone() && futureTask2.isDone()){
  27. System.out.println("Done");
  28. //shut down executor service
  29. executor.shutdown();
  30. return;
  31. }
  32. if(!futureTask1.isDone()){
  33. //wait indefinitely for future task to complete
  34. System.out.println("FutureTask1 output="+futureTask1.get());
  35. }
  36. System.out.println("Waiting for FutureTask2 to complete");
  37. String s = futureTask2.get(200L, TimeUnit.MILLISECONDS);
  38. if(s !=null){
  39. System.out.println("FutureTask2 output="+s);
  40. }
  41. } catch (InterruptedException | ExecutionException e) {
  42. e.printStackTrace();
  43. }catch(TimeoutException e){
  44. //do nothing
  45. }
  46. }
  47. }
  48. }

输出结果:

  1. FutureTask1 output=pool-1-thread-1
  2. Waiting for FutureTask2 to complete
  3. Waiting for FutureTask2 to complete
  4. Waiting for FutureTask2 to complete
  5. Waiting for FutureTask2 to complete
  6. Waiting for FutureTask2 to complete
  7. FutureTask2 output=pool-1-thread-2
  8. Done

Java线程之FutureTask的更多相关文章

  1. Java线程之 InterruptedException 异常

    Java线程之 InterruptedException 异常   当一个方法后面声明可能会抛出InterruptedException 异常时,说明该方法是可能会花一点时间,但是可以取消的方法. 抛 ...

  2. Java线程之CompletionService批处理任务

    如果你向Executor提交了一个批处理任务,并且希望在它们完成后获得结果,怎么办呢? 为此你可以保存与每个任务相关联的Future,然后不断地调用 timeout为零的get,来检验Future是否 ...

  3. java 线程之executors线程池

    一.线程池的作用 平时的业务中,如果要使用多线程,那么我们会在业务开始前创建线程,业务结束后,销毁线程.但是对于业务来说,线程的创建和销毁是与业务本身无关的,只关心线程所执行的任务.因此希望把尽可能多 ...

  4. java 线程之concurrent中的常用工具 CyclicBarrier

    一.CyclicBarrier CyclicBarrier是一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point).在涉及一组固定大小的线程的程序 ...

  5. C++/Java线程之分

    JAVA线程状态图 1.C++/windows中主线程结束,其他线程必然死亡(即使调用pthread_detach解除父子关系,主线程消亡时也会导致子线程被迫关闭). ----1.1 一个进程中可以有 ...

  6. Java线程之Callable和Future

    本篇说明的是Callable和Future,它俩很有意思的,一个产生结果,一个拿到结果.        Callable接口类似于Runnable,从名字就可以看出来了,但是Runnable不会返回结 ...

  7. Java线程之Synchronized用法

    synchronized是Java中的关键字,是一种同步锁.它修饰的对象有以下几种: 修饰一个代码块,被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码,作用的对象是调用这个代码块的对 ...

  8. Java线程之Java内存模型(jmm)

    一.Java内存模型(jmm) 线程通信 消息传递 重排序 顺序一致性 Happens-Before As-If-Serial

  9. Java线程之Dump

    什么是线程dump Java Thread dump记录了线程在jvm中的执行信息,可以看成是线程活动的日志.Java线程转储文件有助于分析应用程序和死锁情况中的瓶颈. 如何获取线程转储文件 在这里, ...

随机推荐

  1. JS基础_运算符的优先级

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  2. 【题解】codevs 3044 矩形面积合并

    传送门 3044 矩形面积求并 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond 题目描述 Description 输入n个矩形,求他们总共占地面积(也就是求一下 ...

  3. jquery.validate.js表单验证 jquery.validate.js的用法

    jquery.validate.js这个插件已经用了2年多了,是一个不可多得的表单验证最方便快捷的插件.基于jquery的小插件,基本小白一学就会上手,对于项目表单页面比较多,元素比较多的校验,该插件 ...

  4. vue 登录 + 记住密码 + 密码加密解密

    <template> <el-form :model="ruleForm"> <h3 class="title">系统登录& ...

  5. Java高并发程序设计学习笔记(八):NIO和AIO

    转自:https://blog.csdn.net/dataiyangu/article/details/87214773 什么是NIOBuffer && ChannelBuffer举个 ...

  6. Linux系统目录结构和文件基本属性

    一.Linux系统目录结构 二.Linux 文件基本属性 三.touch stat tar 命令 一.Linux系统目录结构 不同颜色文件的含义: inux 文件颜色的含义,蓝色代表目录,绿色代表可执 ...

  7. mysql使用存储过程,批量生成测试数据

    1.存储过程代码 delimiter $$DROP PROCEDURE IF EXISTS create_service_data$$create procedure create_service_d ...

  8. 获取iframe子页面内容高度给iframe动态设置高度

    <!DOCTYPE html><html> <head> <meta charset="UTF-8" /> <meta nam ...

  9. Intellij IDEA导入java项目看不到左边的项目目录结构

    1 重新import项目 然后导入完成,就可以了,再不行的话,删除.idea文件,重新import整个Project

  10. 第十章· Logstash深入-Logstash与Redis那点事

    Logstash将日志写入Redis 为什么要使用Redis 在企业中,日志规模的量级远远超出我们的想象,这就是为什么会有一家公司日志易专门做日志收集,给大型金融公司收集日志,比如银行,因为你有可能看 ...