1.FutureTask简介

在Executors框架体系中,FutureTask用来表示可获取结果的异步任务。FutureTask实现了Future接口,FutureTask提供了启动和取消异步任务,查询异步任务是否计算结束以及获取最终的异步任务的结果的一些常用的方法。通过get()方法来获取异步任务的结果,但是会阻塞当前线程直至异步任务执行结束。一旦任务执行结束,任务不能重新启动或取消,除非调用runAndReset()方法。在FutureTask的源码中为其定义了这些状态:

private static final int NEW          = 0;
private static final int COMPLETING   = 1;
private static final int NORMAL       = 2;
private static final int EXCEPTIONAL  = 3;
private static final int CANCELLED    = 4;
private static final int INTERRUPTING = 5;
private static final int INTERRUPTED  = 6;

另外,在《java并发编程的艺术》一书,作者根据FutureTask.run()方法的执行的时机,FutureTask分为了3种状态:

  1. 未启动。FutureTask.run()方法还没有被执行之前,FutureTask处于未启动状态。当创建一个FutureTask,还没有执行FutureTask.run()方法之前,FutureTask处于未启动状态。

  2. 已启动。FutureTask.run()方法被执行的过程中,FutureTask处于已启动状态。

  3. 已完成。FutureTask.run()方法执行结束,或者调用FutureTask.cancel(...)方法取消任务,或者在执行任务期间抛出异常,这些情况都称之为FutureTask的已完成状态。

下图总结了FutureTask的状态变化的过程:

由于FutureTask具有这三种状态,因此执行FutureTask的get方法和cancel方法,当前处于不同的状态对应的结果也是大不相同。这里对get()和cancel()做个总结:

get方法

当FutureTask处于未启动或已启动状态时,执行FutureTask.get()方法将导致调用线程阻塞。如果FutureTask处于已完成状态,调用FutureTask.get()方法将导致调用线程立即返回结果或者抛出异常

cancel方法

当FutureTask处于未启动状态时,执行FutureTask.cancel()方法将此任务永远不会执行;

当FutureTask处于已启动状态时,执行FutureTask.cancel(true)方法将以中断线程的方式来阻止任务继续进行,如果执行FutureTask.cancel(false)将不会对正在执行任务的线程有任何影响;

FutureTask处于已完成状态时,执行FutureTask.cancel(...)方法将返回false。

对Future的get()方法和cancel()方法用下图进行总结

2. FutureTask的基本使用

FutureTask除了实现Future接口外,还实现了Runnable接口。因此,FutureTask可以交给Executor执行,也可以由调用的线程直接执行(FutureTask.run())。另外,FutureTask的获取也可以通过ExecutorService.submit()方法返回一个FutureTask对象,然后在通过FutureTask.get()或者FutureTask.cancel()方法。

应用场景:当一个线程需要等待另一个线程把某个任务执行完后它才能继续执行,此时可以使用FutureTask。假设有多个线程执行若干任务,每个任务最多只能被执行一次。当多个线程试图执行同一个任务时,只允许一个线程执行任务,其他线程需要等待这个任务执行完后才能继续执行。

参考文献

《java并发编程的艺术》

23.FutureTask基本操作总结的更多相关文章

  1. vc++基础班[23]---文件夹的基本操作

      ①.文件夹的创建:CreateDirectory ※※※ 注意:此函数只能创建一层目录,比如想在 C 盘下的 Temp 目录下创建新目录为:123 那么前提是 Temp 这个目录存在才可以!   ...

  2. java多线程的状态转换以及基本操作

    1. 新建线程 一个java程序从main()方法开始执行,然后按照既定的代码逻辑执行,看似没有其他线程参与,但实际上java程序天生就是一个多线程程序,包含了:(1)分发处理发送给给JVM信号的线程 ...

  3. 一、Redis基本操作——String(原理篇)

    小喵的唠叨话:最近京东图书大减价,小喵手痒了就买了本<Redis设计与实现>[1]来看看.这里权当小喵看书的笔记啦.这一系列的模式,主要是先介绍Redis的实现原理(可能很大一部分会直接照 ...

  4. MySQL学习笔记02_数据库和表的基本操作

    02_1 操作数据库 (1)创建数据库 CREATE DATABASE [IF NOT EXISTS] db_name [create_specification[, create_specifica ...

  5. [.net 面向对象程序设计进阶] (23) 团队开发利器(二)优秀的版本控制工具SVN(上)

    [.net 面向对象程序设计进阶] (23) 团队开发利器(二)优秀的版本控制工具SVN(上) 本篇导读: 上篇介绍了常用的代码管理工具VSS,看了一下评论,很多同学深恶痛绝,有的甚至因为公司使用VS ...

  6. sqlalchemy(一)基本操作

    sqlalchemy(一)基本操作 sqlalchemy采用简单的Python语言,为高效和高性能的数据库访问设计,实现了完整的企业级持久模型. 安装 需要安装MySQLdb pip install ...

  7. Jetty使用教程(四:23)—Jetty开发指南

    二十三.Maven和Jetty 这一章节将说明如何通过Maven管理Jetty和使用Jetty的Maven插件. 23.1 使用Maven Apache Maven是一个款软件项目管理工具.基于项目对 ...

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

    作者:海子 出处:http://www.cnblogs.com/dolphin0520/ 本博客中未标明转载的文章归作者海子和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置 ...

  9. 理解 OpenStack + Ceph (7): Ceph 的基本操作和常见故障排除方法

    本系列文章会深入研究 Ceph 以及 Ceph 和 OpenStack 的集成: (1)安装和部署 (2)Ceph RBD 接口和工具 (3)Ceph 物理和逻辑结构 (4)Ceph 的基础数据结构 ...

随机推荐

  1. 转载SQL_trace 和10046使用

    SQL_TRACE是Oracle提供的用于进行SQL跟踪的手段,是强有力的辅助诊断工具.在日常的数据库问题诊断和解决中,SQL_TRACE是非常常用的方法.本文就SQL_TRACE的使用作简单探讨,并 ...

  2. JDBC—DAO

    一.JDBC 什么是JDBC?JAVA DataBase Connectivity (Java 数据库连接技术)由Java编写的一组类和接口组成,为各种类型的数据库提供统一的访问.JDBC的作用?一种 ...

  3. 基于HTML5 FileSystem API的使用介绍(转)

    FileSystem提供了文件夹和文件的创建.移动.删除等操作,大大方便了数据的本地处理, 而且所有的数据都是在沙盒(sandboxed)中,不同的web程序不能互相访问,这就保证了数据 的完整和安全 ...

  4. Https之秘钥交换过程分析

    一.概念回顾 A <------M------> B场景:A.B两个人之间通讯,A传输信息M给B,假定是在不安全的通路上传输. 1.明文传输 被中间人C拦截下来,可以随意篡改A发送给B的消 ...

  5. Codeforces Round #412 (rated, Div. 2, base on VK Cup 2017 Round 3) A Is it rated?

    地址:http://codeforces.com/contest/807/problem/C 题目: C. Success Rate time limit per test 2 seconds mem ...

  6. [转]Raanan Fattal - Image and Video Upscaling from Local Self-Examples 图像放大

    转自:http://www.sigvc.org/bbs/thread-1032-1-1.html 论文链接:http://www.cs.huji.ac.il/~raananf/projects/lss ...

  7. 利用page_source抓取网页中的URL,进行链接测试

    selenium的page_source方法可以获取到页面源码,下面就把它应用到链接测试中. # coding:utf-8 __author__ = 'helen' import re,request ...

  8. C#使用window API 控制打印纸张大小(转载)

    windows一个特点就是设备无关性,这样就给程序控制打印机提供了很好的方法. 首先引用“泥人张”写的打印API类. using System;using System.Collections;usi ...

  9. Extjs 正则表达式 常用的

    extjs正则表达式验证 2011年10月10日 10:36:05 阅读数:7305   在EXT中使用正则表达式验证的方法:fieldLabel : '员工号',name : 'employee.e ...

  10. Linux 实时性能测试工具——Cyclictest

    Cyclictest 是 rt-tests 下的一个测试工具,也是rt-tests 下使用最广泛的测试工具,一般主要用来测试使用内核的延迟,从而判断内核的实时性. 1.2 cyclictest 安装 ...