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. 西部数码虚拟空间配置ssl

    1.在阿里云申请ssl证书 2.解析到西部数码cname地址 3.西部数码---> 申请ssl部署 4.申请托管证书 5.部署https后设置301跳转将http跳转到https  参照: ht ...

  2. vue css背景图片打包后路径问题

    limit,代表如果小于大约4k则会自动帮你压缩成base64编码的图片,否则拷贝文件到生产目录 name,后面是打包后的路径: loader,后面 limit 字段代表图片打包限制,这个限制并不是说 ...

  3. python爬虫套件在mac上的安装-bs的安装

    1,首先安装pip gem install pip 这种方式会报错: ERROR:  While executing gem ... (Gem::FilePermissionError) You do ...

  4. Day03_Python知识总结

    1.元组:  元组其实跟列表差不多,也是存一组数,但它一旦创建便不能修改,所以又叫只读列表. names = ("alex","jack","eric ...

  5. python学习笔记——(三)文件操作

    ·集合操作及其相应的操作符表示集合中没有插入,只有添加,因为毕竟无序 #!/usr/bin/env python # -*- coding:utf-8 -*- # Author:Vergil Zhan ...

  6. cobbler批量化安装系统

  7. 04PHP HTML状态保持

    HTTP无状态:会话时没有储存数据 HTTP状态保持: 1.Cookie:保存在浏览器   $_COOKIE[ ] 超全局变量  数组 不安全,用户可清楚数据时把Cookie清除 ==目的:多页面之间 ...

  8. jquery 禁止回车事件响应

    $(this).keydown( function(e) { var key = window.event?e.keyCode:e.which; if(key.toString() == " ...

  9. Java面试题2

    类加载机制 Java虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的加载机制. 类从被加载到虚拟机内存中开 ...

  10. socket端口绑定后通过bat干掉

    @echo off::port为需要去绑定端口set port=8888for /f "tokens=5 delims= " %%a in ('netstat -ano ^|fin ...