1.callable的使用方法

1.1首先实例化一个Callable

private static class UseCallable implements Callable<返回值类型>{private int sum;@Override//call方法可以抛异常,像线程里面的run方法最多只能在run方法内trycatchpublic 返回值类型 call() throws Exception {//所需要实现的功能代码}}

1.2创建一个future,将callable的实例类传进去

FutureTask<Integer> futureTask = new FutureTask<>(useCallable);
1.3 创建线程将futureTask任务类,将futuretask传入进去
new Thread(futureTask).start();

2.为何能带有返回值?源码解析

由上图我们可以清晰的明白我们的callable的实例是放在FutureTask中的,而在FutureTask的源码中可以看到如下的属性

      /** The underlying callable; nulled out after running */private Callable<V> callable;/** The result to return or exception to throw from get() */private Object outcome; // non-volatile, protected by state reads/writes/** The thread running the callable; CASed during run() */private volatile Thread runner;/** Treiber stack of waiting threads */private volatile WaitNode waiters;

可以看到具有一个outcome属性,这个属性就用来存储我们的callable执行后的返回值

在源码中对其方法有两个实现的赋值方法:

对于下面两种方法中的unsafe方法中的cas操作,待我下篇文章解析unsafe类

第一种,正常设置值

protected void set(V v) {if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {outcome = v;UNSAFE.putOrderedInt(this, stateOffset, NORMAL); // final statefinishCompletion();}}

第二种就是异常

protected void setException(Throwable t) {if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {outcome = t;UNSAFE.putOrderedInt(this, stateOffset, EXCEPTIONAL); // final statefinishCompletion();}}

在future的run方法中就实现了对上面两种方法的调用

 public void run() {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 {result = c.call();//这里就对call方法进行了记录ran = true;} catch (Throwable ex) {result = null;ran = false;setException(ex);//*****}if (ran)set(result);//******   在这里实现了对set方法,也就实现了对 outcome的赋值}} 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 interruptsint s = state;if (s >= INTERRUPTING)handlePossibleCancellationInterrupt(s);}}

所以从上面的分析就可以得出,我们可以通过FutureTask的get()得到callable的结果

3.总结:

callable是实现线程的一种处理方式,他的优点就是具有返回值,还可以有异常的抛出,并且在源码中可以看出在futuretask中对源码进行的处理。

最后在理一遍callable的处理流程 以及

callable的实例化类——传入———>FutuTask的任务类中——传入——>new Thread(future).start

FutureTask是继承自RunnableFuture 实现了Runnable 接口 和 Future 接口。

callable的使用方法详解相关推荐

  1. python的装饰器迭代器与生成器_python3 装饰器、列表生成器、迭代器、内置方法详解等(第四周)...

    前言: 为什么要学习python3? 原因: 1.学习一门语言能力 2.通过该语言能力完成测试自动化以及独立完成自测框架知识 那么我要做什么呢? 1.每天花十个小时完成python3的学习 要在什么地 ...

  2. python怎么横着输出_对python3中, print横向输出的方法详解

    对python3中, print横向输出的方法详解 Python 2 : print打印的时候,如果结尾有逗号,打出来时候不会换行.但是在python3里面就不行了. Python3: 3.0的pri ...

  3. 线程池invokeAll方法详解

    线程池invokeAll方法详解 问题起源与抽象 问题排查与猜测 猜测一:invokeAll 在异步执行后会不会同步等待线程执行完毕获取最终结果 猜测二:队列里面可能存在第一次调用 invokeAll ...

  4. python统计csv行数_对Python 多线程统计所有csv文件的行数方法详解

    如下所示: #统计某文件夹下的所有csv文件的行数(多线程) import threading import csv import os class MyThreadLine(threading.Th ...

  5. python修改文件内容_Python批量修改文本文件内容的方法详解

    这篇文章主要介绍了Python批量修改文本文件内容的方法的相关资料,需要的朋友可以参考下 Python批量替换文件内容,支持嵌套文件夹 import os path="./" fo ...

  6. python二维元组_python中读入二维csv格式的表格方法详解(以元组/列表形式表示)

    如何去读取一个没有表头的二维csv文件(如下图所示)? 并以元组的形式表现数据: ((1.0, 0.0, 3.0, 180.0), (2.0, 0.0, 2.0, 180.0), (3.0, 0.0, ...

  7. Spring JdbcTemplate方法详解

    2019独角兽企业重金招聘Python工程师标准>>> Spring JdbcTemplate方法详解 标签: springhsqldbjava存储数据库相关sql 2012-07- ...

  8. golang 解析php序列化,golang实现php里的serialize()和unserialize()序列和反序列方法详解...

    Golang 实现 PHP里的 serialize() . unserialize() 安装 go get -u github.com/techleeone/gophp/serialize 用法 pa ...

  9. ES5和ES6数组遍历方法详解

    ES5和ES6数组遍历方法详解 在ES5中常用的10种数组遍历方法: 1.原始的for循环语句 2.Array.prototype.forEach数组对象内置方法 3.Array.prototype. ...

  10. linux expect 输入密码,shell脚本无密码登录 expect的使用方法详解

    shell脚本无密码登录 expect的使用方法详解 今天需要做一个定时任务脚本将最新的数据包文件传到远程的服务器上,虽然有密钥但也是要求输入密码的那种,所以只能另想办法实现让脚本自动输入密码了. 从 ...

最新文章

  1. 值得期待的.Net Micro Framework 3.0
  2. Xamarin Essentials教程剪贴板Clipboard
  3. 支付宝开发中return_url和notify_url的区别分析
  4. 在控制台输出九九乘法表
  5. python网络协议编辑器_python模块:网络协议和支持
  6. apache tomcat (catalina)查版本(solaris/unix)
  7. win10透明任务栏_TranslucentTB打造win10透明任务栏
  8. hget如何获取多个value_《深入微服务》之 如何给老婆解释什么是微服务的基础框架SpringBoot?...
  9. statspack report分析
  10. 测试过程中常用的linux命令之【删除指定的文件行】
  11. 宏基因组 微生物组 微生物生态领域杂志简介及最新影响因子
  12. stm32实验报告心得体会_stm32实验报告心得体会
  13. 万变不离CHP 天霆“交付”多元化应用
  14. php 5.3.3 + 中 php-fpm 的重启、终止操作命令
  15. 什么是元数据(Metadata)
  16. python 3.5 urllib
  17. 《启示录:打造用户喜爱的产品》第一部分 人员6 招聘产品经理
  18. 软件测试 pytest pytest的命名规则 用例的前后置 conftest.py 定制allure报告 @pytest.mark.parametrize()装饰器作数据驱动
  19. java图形化Swing教程(一)
  20. nio tcp 释放_java socket nio 运行时间久 有掉包现象 而且 运行 缓慢

热门文章

  1. c++实训 数组之犯二程度 与队列变换
  2. XLua官方Examples 08_Hotfix 热补丁的示例【2】
  3. java 箭头符号_箭头符号大全
  4. win10家庭中文版升级专业版心得
  5. [机缘参悟-74]:沟通技巧-无论在职场还是在家,尽量少用反问句
  6. DTMF双音多频信号仿真演示系统
  7. 《Linux运维实战:搭建自己的Confluence知识管理系统》
  8. 2048游戏DQN实验
  9. 可变剪接分析流程(rMATS)
  10. python设置代理_python使用代理proxy