此文承接之前的博文 解开Future的神秘面纱之取消任务 补充一些任务执行的一些细节,并从全局介绍程序的运行情况。
  
  任务提交到执行的流程
  
  前文我们已经了解到一些Future的实现细节,这里我们来梳理一下运行流程。这里只说sumbit(提交)
  
  (1)客户端创建一个Callable或Runnable对象。
  
  (2)客户端调用ExecutorService的submit方法,将任务提交给执行器。
  
  (3)ExecutorService将调用其实现类AbstractExecutorService的submit方法。
  
  (4)submit方法将获取到的Runnable/Callable任务交由其内部方法newTaskFor进行包装。
  
  (5)newTaskFor方法将Runnable/Callable包装成FutureTask对象。
  
  (6)submit把包装好的FutureTask对象交由execute方法执行,此方法有ThreadPoolExecutor提供。
  
  (7)submit方法返回FutreTask对象给客户端。
  
  任务提交为何能接收两种类型的接口?
  
  实际上很有意思的是,FutureTask只使用Callable对象(因为使用Future的初衷就是想要获取任务处理结果),而Executor的execute只接收Runnable对象(执行器只管执行任务)
  
  FutureTask接收到Runnable对象后,会利用适配器,将其适配为Callable对象进行使用。注意,Runnable适配后,返回值基本没什么意义,都是写死的。
  
  而FutureTask实际上相当于Runnable对象的装饰器,FutureTask的继承结构如图所示:
  
  我们知道Runnable定义了任务该做什么,Future定义了任务的控制操作,而RunnableFuture接口兼具这两个功能。
  
  Future就是实现这组操作的实现类,它也是Runnable的装饰器类,Runnable任务在经过其包装后,仍然还是Runnable,不影响其交给execute方法执行。而且他实现了Future接口,也就可以根据它对任务进行控制。
  
  FutureTask有哪些字段,用来做什么的?
  
  (1)state => 状态,用于基于状态的控制操作。
  
  NEW => 新建任务
  
  COMPLETING www.tygj178.com=> 正在完成,即任务已经被线程启动
  
  NORMAL => 正常完成任务
  
  EXCEPTIONAL => 任务因为异常而终止
  
  CANCELLED => 任务已被取消,注意这里并不表示任务实际状态,即任务可能还在运行。
  
  INTERRUPTING => 中断任务中
  
  INTERRUPTD => 任务已被中断
  
  (2)callable www.ysyl157.com=> callable任务,实际被执行的任务
  
  (3)outcome => 执行结果
  
  (4)runner => 执行线程的引用,用来控制任务的执行。
  
  (5)waiters => 等待线程队列,当任务还未完成时,用于保存因为获取结果的而被阻塞的线程。
  
  FutureTask的状态变化
  
  (1)NEW -> COMPLETING -> NORMAL(任务正常执行到结束)
  
  (2)NEW -> COMPLETING -> EXCEPTIONAL(任务执行过程中出现异常)
  
  (3)NEW -> CANCELLED (任务被取消)
  
  (4)NEW -> INTERRUPTING -> INTERRUPTED (任务已经开始,尚未完成就被取消)
  
  FutureTask如何确定其执行线程的?
  
  任务的控制最主要的两个功能就是取消和获取结果。取消的操作,上一篇博文已经讲到了,获取结果将于下篇讲述。这里补充前篇的一些内容,也就是取消操作相关的细节,当时已经获知,要取消任务,实际上是通过中断任务的执行线程实现的,如图:
  
  FutureTask的cancel方法
  
  // The Vue build version to load with the `import` command
  
  // (runtime-only or standalone)www.xinghenyule.com has been set in webpack.base.conf with an alias.
  
  import Vue from 'vue'
  
  import App from './App'
  
  import router from './router'
  
  import boostrap from 'bootstrap/dist/css/bootstrap.css'
  
  import store from 'www.ylouyi3.com./store/index.js'
  
  Vue.config.productionTip = false
  
  /* eslint-disable no-new */
  
  new Vue({
  
  el: '#app',
  
  router,
  
  store,//在全局对象上加载仓库
  
  components: { App },
  
  template: 'www.dasheng178.com<App/>'
  
  })
  
  两个组件
  
  +
  
  navbar.vue
  
  +
  
  product.vue 该组件用于显示商品的详细信息
  
  +
  
  程序入口APP.vue
  
  <template>
  
  <div id="app">
  
  <nav-bar>www.yinmaoyule178.com</nav-bar>
  
  <router-view>www.chaoyueyule.net</router-view>
  
  </div>
  
  </template>
  
  <script>
  
  import NavBar from 'www.dfgjpt.com/./views/components/navbar'
  
  export default {
  
  name: 'App',
  
  components:{NavBar}
  
  }
  
  </script>
  
  但是,这个runner是何时被赋值的,我当时并不清楚,查阅源码也没发现什么setRunner之类的代码。后来突然想到,只有在任务被执行的时候才能知道,它到底被哪个线程执行。于是才注意到了这段CAS的代码,(当时不太懂,所以就算看到了这段代码,也不明白)。意思就是说,如果当前对象的runner字段值为null,就将其设置为当前的执行线程。到这里,我们就有了此线程的引用。
  
  FutureTask到达ThreadPoolExecutor的execute之后,是什么情形?
  
  这里简要说一下,任务到达ThreadPoolExecutor之后,线程池会根据当前线程数量的情况进行处理,可能创建一个新线程来执行,或者加入到任务队列等待执行,再或者就是被线程池抛弃等等。
  
  相关细节可查看,我关于ThreadPoolExecutor的相关博文。

解开Future的神秘面纱之任务执行的更多相关文章

  1. 揭开Future的神秘面纱——任务执行

    前言 此文承接之前的博文 解开Future的神秘面纱之取消任务 补充一些任务执行的一些细节,并从全局介绍程序的运行情况. 系列目录 揭开Future的神秘面纱——任务取消 揭开Future的神秘面纱— ...

  2. 揭开Future的神秘面纱——结果获取

    前言 在前面的两篇博文中,已经介绍利用FutureTask任务的执行流程,以及利用其实现的cancel方法取消任务的情况.本篇就来介绍下,线程任务的结果获取. 系列目录 揭开Future的神秘面纱—— ...

  3. 揭开Future的神秘面纱——任务取消

    系列目录: 揭开Future的神秘面纱——任务取消 揭开Future的神秘面纱——任务执行 揭开Future的神秘面纱——结果获取 使用案例 在之前写过的一篇随笔中已经提到了Future的应用场景和特 ...

  4. JavaScript基本知识点——带你逐步解开JS的神秘面纱

    JavaScript基本知识点--带你逐步解开JS的神秘面纱 在我们前面的文章中已经深入学了HTML和CSS,在网页设计中我们已经有能力完成一个美观的网页框架 但仅仅是网页框架不足以展现出网页的魅力, ...

  5. 解开HTTPS的神秘面纱

    在说HTTP前,一定要先介绍一下HTTP,这家伙应该不用过多说明了,大家每天都在用,每一次HTTP请求,都是一次TCP连接.遗憾的是,请求的内容在TCP报文中是明文传输的,任何人截取到请求都可以读取其 ...

  6. 揭开Docker的神秘面纱

    Docker 相信在飞速发展的今天已经越来越火,它已成为如今各大企业都争相使用的技术.那么Docker 是什么呢?为什么这么多人开始使用Docker? 本节课我们将一起解开Docker的神秘面纱. 本 ...

  7. 揭开Redis的神秘面纱

    本篇博文将为你解开Redis的神秘面纱,通过阅读本篇博文你将了解到以下内容: 什么是Redis? 为什么选择 Redis? 什么场景下用Redis? Redis 支持哪些语言? Redis下载 Red ...

  8. 解开lambda最强作用的神秘面纱

    我们期待了很久lambda为java带来闭包的概念,但是如果我们不在集合中使用它的话,就损失了很大价值.现有接口迁移成为lambda风格的问题已经通过default methods解决了,在这篇文章将 ...

  9. 解开SQL注入的神秘面纱-来自于宋沄剑的分享

    解开SQL注入的神秘面纱-来自于宋沄剑的分享 https://files.cnblogs.com/files/wxlevel/揭开SQL注入的神秘面纱.pdf

随机推荐

  1. uvm_comps.svh

    UVM的文件组织方式很有意思,比如,在src/comps/ 下的所有文件都通过uvm_comps.svh 包含进去. `include "comps/uvm_pair.svh" ` ...

  2. linux 删除文件后空间没有释放的解决办法

    清空没用的文件,当我删除文件后,发现可用空间沒有变化 os:centos4.7 现象: 发现当前磁盘空间使用情况: [root@ticketb ~]# df -hFilesystem          ...

  3. 一次性删除数据库所有表和所有存储过程 SQL语句

    一次性删除数据库所有表和所有存储过程 SQL语句 今天转移数据库数据,需要把数据库原来的表和存储过程清空.删除所有的表:如果由于外键约束删除table失败,则先删除所有约束: --/第1步****** ...

  4. HDU 1950 Bridging signals (LIS,O(nlogn))

    题意: 给一个数字序列,要求找到LIS,输出其长度. 思路: 扫一遍+二分,复杂度O(nlogn),空间复杂度O(n). 具体方法:增加一个数组,用d[i]表示长度为 i 的递增子序列的最后一个元素, ...

  5. HDU 1729 Stone Game 石头游戏 (Nim, sg函数)

    题意: 有n个盒子,每个盒子可以放一定量的石头,盒子中可能已经有了部分石头.假设石头无限,每次可以往任意一个盒子中放石头,可以加的数量不得超过该盒中已有石头数量的平方k^2,即至少放1个,至多放k^2 ...

  6. jni 开发

    创建android工程 -> 添加native 函数 添加库之后: 1. 用javah 生成c语言.h头文件时, 在cmd 窗口中cd 到bin/classes 目录下执行下代码无效: java ...

  7. 【page-monitor 前端自动化 中篇】 源码分析

    转载文章:来源(靠谱崔小拽) 上篇中初探了page-monitor的一些功能和在前端自动化测试方面的可行性,本篇主要分析下page-monitor的实现方式和源码. mode-module简介 pag ...

  8. 实验十一 团队作业7:团队项目设计完善&编码

    实验十一 团队作业7:团队项目设计完善&编码 实验时间 2019-6-6 Deadline: 2019-6-12 10:00,以团队随笔博文提交至班级博客的时间为准. 评分标准: 按时交 – ...

  9. 使用gcc -g编译,gdb调试时仍然存在“no debug symbols found”的错误

    今天为调试一段代码,使用gcc将程序用-g选项重新编译.但是使用gdb进行debug时,仍然出现“no debug symbols found”的错误.仔细检查了一下Makefile,原来后面定义的连 ...

  10. PAT (Basic Level) Practise (中文)-1037. 在霍格沃茨找零钱(20)

    PAT (Basic Level) Practise (中文)-1037. 在霍格沃茨找零钱(20) http://www.patest.cn/contests/pat-b-practise/1037 ...