1. 基本概念

    <1>Callable,Callable和Runnable差不多,两者都是为那些其实例可能被另一个线程执行的类而设计的,最主要的差别在于Runnable不会

    返回线程运算结果,Callable可以(假如线程需要返回运行结果)。

    <2>Future,是一个接口表示异步计算的结果,它提供了检查计算是否完成的方法,以等待计算的完成,并获取计算的结果。

    <3>FutureTask是Future的实现类,也可以说是进阶类,优化了Future的一些缺点,比如Future.get会阻塞等等,它提供了对Future的基本实现。

    可使用FutureTask包装Callable或Runnable对象,实现异步处理线程运行结果。FutureTask实现了Runnable和Future(看源码可以看出来),所以也可以

    将FutureTask提交给Executor。一般使用FutureTask代替Future即可。

  2. 使用api

    <1>Callable使用方法

            call()  //类似run()方法
<2>Future使用方法
            cancel(boolean mayInterruptIfRunning)  //取消任务,如果已经完成,返回false
isCancelled() //判断是否取消过
isDone() //判断是否完成,取消、完成、异常都会返回true
get() //获取执行结果,阻塞的
<3>FutureTask使用方法
            cancel(boolean mayInterruptIfRunning)
isCancelled()
done() //重写它来实现异步处理线程执行结果
isDone()
run()
get()
  1. 使用示例
    Callable+Futrue

    private  static class CallableThread implements Callable<String>{
@Override
public String call() throws Exception {
System.out.println("进入CallableThread的call()方法, 开始睡觉, 睡觉时间为" + System.currentTimeMillis());
Thread.sleep(10000);
System.out.println("睡觉结束");
return "123";
}
} @Test
public void test2(){
ExecutorService executorService = Executors.newCachedThreadPool();
CallableThread callableThread = new CallableThread();
long l = System.currentTimeMillis();
System.out.println("任务提交前时间:" + l);
Future<String> submit = executorService.submit(callableThread);
try {
String s = submit.get();
}catch (Exception e){
}
System.out.println("获取结果的时间:" + (System.currentTimeMillis()-l));
}

执行结果

    任务提交前时间:1556438172228
进入CallableThread的call()方法, 开始睡觉, 睡觉时间为1556438172229
睡觉结束
获取结果的时间:10006

这里的 Future.get 是阻塞方法 , 会一直等待Callable中线程任务执行完毕,是很低下的效率,

解决方式

1.可以使用FutureTask ,重写done方法

2.循环判断isDone,返回true的时候然后调用get()获取

    Callable+FutureTask,异步处理线程运行结果

    private  static class CallableThread implements Callable<String>{
@Override
public String call() throws Exception {
System.out.println("进入CallableThread的call()方法, 开始睡觉, 睡觉时间为" + System.currentTimeMillis());
Thread.sleep(10000);
System.out.println("睡觉结束");
return "123";
}
}
private class MyFutureTask extends FutureTask<String>{
public MyFutureTask(Callable callable){
super(callable);
} //FutureTask任务完成,会回调这个方法
@Override
protected void done() {
System.out.println("执行完调用了done()");
super.done();
try {
String s = this.get();
System.out.println("任务执行完毕:" + s);
System.out.println("当前时间:" + System.currentTimeMillis()); }catch (Exception e){
}
}
} @Test
public void test3() {
ExecutorService executorService = Executors.newCachedThreadPool();
CallableThread callableThread = new CallableThread();
MyFutureTask myFutureTask = new MyFutureTask(callableThread);
executorService.submit(myFutureTask);
System.out.println("主线程执行结束");
try {
executorService.shutdown();
executorService.awaitTermination(12,TimeUnit.SECONDS);
} catch (Exception e) {
}finally {
executorService.shutdownNow();
}
}

执行结果

     执行结果如下
主线程执行结束
进入CallableThread的call()方法, 开始睡觉, 睡觉时间为1556416923492
睡觉结束
执行完调用了done()
任务执行完毕:123
当前时间:1556416933493

java核心-多线程-线程类-Callable、Future和FutureTask的更多相关文章

  1. Java并发编程:ThreadPoolExecutor + Callable + Future(FutureTask) 探知线程的执行状况

    如题 (总结要点) 使用ThreadPoolExecutor来创建线程,使用Callable + Future 来执行并探知线程执行情况: V get (long timeout, TimeUnit ...

  2. java核心-多线程-Java多线程编程涉及到包、类

    Java有关多线程编程设计的类主要涉及两个包java.lang和java.util.concurrent两个包 java.lang包,主要是线程基础类 <1>Thread <2> ...

  3. Java自学-多线程 线程安全的类

    Java常见的线程安全相关的面试题 步骤 1 : HashMap和Hashtable的区别 HashMap和Hashtable都实现了Map接口,都是键值对保存数据的方式 区别1: HashMap可以 ...

  4. java核心-多线程(1)-知识大纲

    Thread,整理一份多线程知识大纲,大写意 1.概念介绍 线程 进程 并发 2.基础知识介绍 Java线程类 Thread 静态方法&实例方法 Runnable Callable Futur ...

  5. 多线程,线程类三种方式,线程调度,线程同步,死锁,线程间的通信,阻塞队列,wait和sleep区别?

    重难点梳理 知识点梳理 学习目标 1.能够知道什么是进程什么是线程(进程和线程的概述,多进程和多线程的意义) 2.能够掌握线程常见API的使用 3.能够理解什么是线程安全问题 4.能够知道什么是锁 5 ...

  6. 2019.12.12 Java的多线程&匿名类

    Java基础(深入了解概念为主) 匿名类 定义 Java匿名类很像局部或内联系,只是没有明细.我们可以利用匿名类,同时定义并实例化一个类.只有局部类仅被使用一次时才应该这么做. 匿名类不能有显式定义的 ...

  7. Java中多线程同步类 CountDownLatch

    在多线程开发中,常常遇到希望一组线程完成之后在执行之后的操作,java提供了一个多线程同步辅助类,可以完成此类需求: 类中常见的方法: 其中构造方法:CountDownLatch(int count) ...

  8. Java基础-多线程-③线程同步之synchronized

    使用线程同步解决多线程安全问题 上一篇 Java基础-多线程-②多线程的安全问题 中我们说到多线程可能引发的安全问题,原因在于多个线程共享了数据,且一个线程在操作(多为写操作)数据的过程中,另一个线程 ...

  9. Java基础-多线程-①线程的创建和启动

    简单阐释进程和线程 对于进程最直观的感受应该就是“windows任务管理器”中的进程管理: (计算机原理课上的记忆已经快要模糊了,简单理解一下):一个进程就是一个“执行中的程序”,是程序在计算机上的一 ...

随机推荐

  1. Github远程仓库提交代码步骤

    1.克隆远程仓库     1)当没有设置默认目录时         git clone 仓库地址 本地存放目录 //没有目录的情况    2)当设置了本地存放目录时         先打开路径,命令: ...

  2. C# copy() 与 Clone()区别

    copy() 与 Clone()都创建了一个新对象 DataTable dt=new DataTable();DataTable dtcopy=dt.copy();      //copy复制的是值和 ...

  3. 安装Java8以后,Eclipse运行异常解决方案

    再输入cmd,java后提示运行环境配置中,安装的是jdk1.7,但要求是jdk1.8,也就是说Java8. 网上删除注册表,下载彻底清除软件均不能解决问题的,请按照下边提示完成操作即可. 1.在文件 ...

  4. sublime text常用快捷键及多行光标批量操作教程

    sublime text常用快捷键及多行光标批量操作教程   版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/a772304419/article/d ...

  5. Python 列表(List)

    Python 列表(List) 序列是Python中最基本的数据结构.序列中的每个元素都分配一个数字 - 它的位置,或索引,第一个索引是0,第二个索引是1,依此类推. Python有6个序列的内置类型 ...

  6. Feign源码解析系列-最佳实践

    前几篇准备写完feign的源码,这篇直接给出Feign的最佳实践,考虑到目前网上还没有一个比较好的实践解释,对于新使用spring cloud的同学会对微服务之间的依赖产生一些迷惑,也会走一些弯路.这 ...

  7. alsa音频播放过程中的基本概念

    以下为 ALSA-Project/FramesPeriods[1] 学习笔记 1, sample_rate: 即每秒进行多少次采样,常见的比如 8000.16000.44100和48000等 2, s ...

  8. 论文笔记——An online EEG-based brain-computer interface for controlling hand grasp using an adaptive probabilistic neural network(10年被引用66次)

    题目:利用自适应概率网络设计一种在线脑机接口楼方法控制手部抓握 概要:这篇文章提出了一种新的脑机接口方法,控制手部,系列手部抓握动作和张开在虚拟现实环境中.这篇文章希望在现实生活中利用脑机接口技术控制 ...

  9. JQuery----操作01

    ---恢复内容开始--- 一 JQuery选择器: 基本选择器和基本过滤器和筛选选择器 基础选择器: <title>Title</title> <script src=& ...

  10. SpringSecurity身份验证基础入门

    对于没有访问权限的用户需要转到登录表单页面.要实现访问控制的方法多种多样,可以通过Aop.拦截器实现,也可以通过框架实现(如:Apache Shiro.Spring Security). pom.xm ...