我的编程空间,编程开发者的网络收藏夹
学习永远不晚

futuretask源码分析(推荐)

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

futuretask源码分析(推荐)

FutureTask只实现RunnableFuture接口:

该接口继承了java.lang.Runnable和Future接口,也就是继承了这两个接口的特性。

可以不必直接继承Thread来生成子类,只要实现run方法,且把实例传入到Thread构造函数,Thread就可以执行该实例的run方法了( Thread(Runnable) )。

可以让任务独立执行,get获取任务执行结果时,可以阻塞直至执行结果完成。也可以中断执行,判断执行状态等。

FutureTask是一个支持取消行为的异步任务执行器。该类实现了Future接口的方法。

如: 1. 取消任务执行

查询任务是否执行完成

获取任务执行结果(”get“任务必须得执行完成才能获取结果,否则会阻塞直至任务完成)。

注意:一旦任务执行完成,则不能执行取消任务或者重新启动任务。(除非一开始就使用runAndReset模式运行任务)
FutureTask支持执行两种任务, Callable 或者 Runnable的实现类。且可把FutureTask实例交由Executor执行。

源码部分(很简单):

public class FutureTask<V> implements RunnableFuture<V> {      private volatile int state;  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;    private Callable<V> callable;    private Object outcome; // non-volatile, protected by state reads/writes    private volatile Thread runner;    private volatile WaitNode waiters;    @SuppressWarnings("unchecked")  private V report(int s) throws ExecutionException {    Object x = outcome;    if (s == NORMAL)      return (V)x;    if (s >= CANCELLED)      throw new CancellationException();    throw new ExecutionException((Throwable)x);  }    public FutureTask(Callable<V> callable) {    if (callable == null)      throw new NullPointerException();    this.callable = callable;    this.state = NEW;    // ensure visibility of callable  }    public FutureTask(Runnable runnable, V result) {    this.callable = Executors.callable(runnable, result);    this.state = NEW;    // ensure visibility of callable  }  //判断任务是否已取消(异常中断、取消等)  public boolean isCancelled() {    return state >= CANCELLED;  }    public boolean cancel(boolean mayInterruptIfRunning) {    if (state != NEW)      return false;    if (mayInterruptIfRunning) {      if (!UNSAFE.compareAndSwapInt(this, stateOffset, NEW, INTERRUPTING))        return false;      Thread t = runner;      if (t != null)        t.interrupt();      UNSAFE.putOrderedInt(this, stateOffset, INTERRUPTED); // final state    }    else if (!UNSAFE.compareAndSwapInt(this, stateOffset, NEW, CANCELLED))      return false;    finishCompletion();    return true;  }    public V get() throws InterruptedException, ExecutionException {    int s = state;    //如果任务未彻底完成,那么则阻塞直至任务完成后唤醒该线程    if (s <= COMPLETING)      s = awaitDone(false, 0L);    return report(s);  }    public V get(long timeout, TimeUnit unit)    throws InterruptedException, ExecutionException, TimeoutException {    if (unit == null)      throw new NullPointerException();    int s = state;    if (s <= COMPLETING &&      (s = awaitDone(true, unit.toNanos(timeout))) <= COMPLETING)      throw new TimeoutException();    return report(s);  }    protected void done() { }    protected void set(V v) {    if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {      outcome = v;      UNSAFE.putOrderedInt(this, stateOffset, NORMAL); // final state      finishCompletion();    }  }    protected void setException(Throwable t) {    if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {      outcome = t;      UNSAFE.putOrderedInt(this, stateOffset, EXCEPTIONAL); // final state      finishCompletion();    }  }    public void run() {    //只有当任务状态=new时才被运行继续执行    if (state != NEW ||      !UNSAFE.compareAndSwapObject(this, runnerOffset,                     null, Thread.currentThread()))      return;    try {      Callable<V> c = callable;      if (c != null && state == NEW) {        V result;        boolean ran;        try {          //调用Callable的Call方法          result = c.call();          ran = true;        } catch (Throwable ex) {          result = null;          ran = false;          setException(ex);        }        if (ran)          set(result);      }    } finally {      // runner must be non-null until state is settled to      // prevent concurrent calls to run()      runner = null;      // state must be re-read after nulling runner to prevent      // leaked interrupts      int s = state;      if (s >= INTERRUPTING)        handlePossibleCancellationInterrupt(s);    }  }    protected boolean runAndReset() {    if (state != NEW ||      !UNSAFE.compareAndSwapObject(this, runnerOffset,                     null, Thread.currentThread()))      return false;    boolean ran = false;    int s = state;    try {      Callable<V> c = callable;      if (c != null && s == NEW) {        try {          c.call(); // don't set result          ran = true;        } catch (Throwable ex) {          setException(ex);        }      }    } finally {      // runner must be non-null until state is settled to      // prevent concurrent calls to run()      runner = null;      // state must be re-read after nulling runner to prevent      // leaked interrupts      s = state;      if (s >= INTERRUPTING)        handlePossibleCancellationInterrupt(s);    }    return ran && s == NEW;  }    private void handlePossibleCancellationInterrupt(int s) {    // It is possible for our interrupter to stall before getting a    // chance to interrupt us. Let's spin-wait patiently.    if (s == INTERRUPTING)      while (state == INTERRUPTING)        Thread.yield(); // wait out pending interrupt    // assert state == INTERRUPTED;    // We want to clear any interrupt we may have received from    // cancel(true). However, it is permissible to use interrupts    // as an independent mechanism for a task to communicate with    // its caller, and there is no way to clear only the    // cancellation interrupt.    //    // Thread.interrupted();  }    static final class WaitNode {    volatile Thread thread;    volatile WaitNode next;    WaitNode() { thread = Thread.currentThread(); }  }    private void finishCompletion() {    // assert state > COMPLETING;    for (WaitNode q; (q = waiters) != null;) {      if (UNSAFE.compareAndSwapObject(this, waitersOffset, q, null)) {        for (;;) {          Thread t = q.thread;          if (t != null) {            q.thread = null;            LockSupport.unpark(t);          }          WaitNode next = q.next;          if (next == null)            break;          q.next = null; // unlink to help gc          q = next;        }        break;      }    }    done();    callable = null;    // to reduce footprint  }    private int awaitDone(boolean timed, long nanos)    throws InterruptedException {    final long deadline = timed ? System.nanoTime() + nanos : 0L;    WaitNode q = null;    boolean queued = false;    for (;;) {            if (Thread.interrupted()) {        removeWaiter(q);        throw new InterruptedException();      }      int s = state;      if (s > COMPLETING) {        if (q != null)          q.thread = null;        return s;      }      else if (s == COMPLETING) // cannot time out yet        Thread.yield();      else if (q == null)        q = new WaitNode();      else if (!queued)        queued = UNSAFE.compareAndSwapObject(this, waitersOffset,                           q.next = waiters, q);      else if (timed) {        nanos = deadline - System.nanoTime();        if (nanos <= 0L) {          removeWaiter(q);          return state;        }        LockSupport.parkNanos(this, nanos);      }      else        LockSupport.park(this);    }  }    private void removeWaiter(WaitNode node) {    if (node != null) {      node.thread = null;      retry:      for (;;) {     // restart on removeWaiter race        for (WaitNode pred = null, q = waiters, s; q != null; q = s) {          s = q.next;          if (q.thread != null)            pred = q;          else if (pred != null) {            pred.next = s;            if (pred.thread == null) // check for race              continue retry;          }          else if (!UNSAFE.compareAndSwapObject(this, waitersOffset, q, s))            continue retry;        }        break;      }    }  }  // Unsafe mechanics  private static final sun.misc.Unsafe UNSAFE;  private static final long stateOffset;  private static final long runnerOffset;  private static final long waitersOffset;  static {    try {      UNSAFE = sun.misc.Unsafe.getUnsafe();      Class<?> k = FutureTask.class;      stateOffset = UNSAFE.objectFieldOffset        (k.getDeclaredField("state"));      runnerOffset = UNSAFE.objectFieldOffset        (k.getDeclaredField("runner"));      waitersOffset = UNSAFE.objectFieldOffset        (k.getDeclaredField("waiters"));    } catch (Exception e) {      throw new Error(e);    }  }}

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

futuretask源码分析(推荐)

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

futuretask源码分析(推荐)

FutureTask只实现RunnableFuture接口: 该接口继承了java.lang.Runnable和Future接口,也就是继承了这两个接口的特性。 1.可以不必直接继承Thread来生成子类,只要实现run方法,且把实例传入到
2023-05-31

Java异步任务计算FutureTask源码分析

本文小编为大家详细介绍“Java异步任务计算FutureTask源码分析”,内容详细,步骤清晰,细节处理妥当,希望这篇“Java异步任务计算FutureTask源码分析”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧
2023-06-30

《Spring Boot源码解读与原理分析》书籍推荐

Spring Boot 1.0.0 早在2014年就已经发布,只不过到了提倡“降本增效”的今天,Spring Boot才引起了越来越多企业的关注。Spring Boot是目前Java EE开发中颇受欢迎的框架之一。依托于底层Spring F
2023-08-17

java使用websocket,并且获取HttpSession 源码分析(推荐)

一:本文使用范围此文不仅仅局限于spring boot,普通的spring工程,甚至是servlet工程,都是一样的,只不过配置一些监听器的方法不同而已。本文经过作者实践,确认完美运行。二:Spring boot使用websocket2.1
2023-05-31

Java异步编程中如何进行FutureTask源码分析

本篇文章给大家分享的是有关Java异步编程中如何进行FutureTask源码分析,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。Java的异步编程是一项非常常用的多线程技术。但之
2023-06-19

docker-cli源码窥探(推荐)

最近一直在使用docker,在这做下记录,本文我将以docker ps -a 命令为例探究docker命令在 client侧的执行过程,源码的版本为20.10,对docker-cli源码知识感兴趣的朋友一起学习下吧
2022-11-16

Java JDK 二分法 分析demo(推荐)

如下所示:public class Test{ public static void main(String[] args) { Long[] arr = new Long[100000]; for(int i =0;i<1
2023-05-31

SpringBoot整合SpringSecurity过滤器链加载执行流程源码分析(最新推荐)

SpringBoot对于SpringSecurity提供了自动化配置方案,可以使用更少的配置来使用SpringSecurity,这篇文章主要介绍了SpringBoot整合SpringSecurity过滤器链加载执行流程源码分析,需要的朋友可以参考下
2023-02-23

nacos注册中心单节点ap架构源码解析(最新推荐)

这篇文章主要介绍了nacos注册中心单节点ap架构源码解析,本文通过示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
2023-01-03

SocketServer 源码分析

Creating network servers.contentsSocketServer.pycontentsfile headBaseServerBaseServer.serve_foreverBaseServer.shutdownBa
2023-01-31

CesiumJS源码分析

这篇文章主要介绍“CesiumJS源码分析”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“CesiumJS源码分析”文章能帮助大家解决问题。1. 有什么光CesiumJS 支持的光的类型比较少,默认场
2023-07-06

RateLimiter 源码分析

俗话说得好,缓存,限流和降级是系统的三把利剑。刚好项目中每天早上导出数据时因调订单接口频率过高,订单系统担心会对用户侧的使用造成影响,让我们对调用限速一下,所以就正好用上了。 常用的限流算法有2种:漏桶算法和令牌桶算法。漏桶算法漏桶算法:请
2023-05-31

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录