zoukankan      html  css  js  c++  java
  • Java多线程:Callable,Future,FutureTask

    一、Future

    Future和Callable基本是成对出现的,Callable负责产生结果,Future负责获取结果。
        1、Callable接口类似于Runnable,只是Runnable没有返回值。
        2、Callable任务除了返回正常结果之外,如果发生异常,该异常也会被返回,即Future可以拿到异步执行任务各种结果;
        3、Future.get方法会导致主线程阻塞,直到Callable任务执行完成;
    Future就是对于具体的Runnable或者Callable任务的执行结果进行取消、查询是否完成、获取结果。必要时可以通过get方法获取执行结果,该方法会阻塞直到任务返回结果。
      
    Future类是一个接口:
       在Future接口中声明了5个方法,下面依次解释每个方法的作用:
    • cancel方法用来取消任务,如果取消任务成功则返回true,如果取消任务失败则返回false。参数mayInterruptIfRunning表示是否允许取消正在执行却没有执行完毕的任务,如果设置true,则表示可以取消正在执行过程中的任务。如果任务已经完成,则无论mayInterruptIfRunning为true还是false,此方法肯定返回false,即如果取消已经完成的任务会返回false;如果任务正在执行,若mayInterruptIfRunning设置为true,则返回true,若mayInterruptIfRunning设置为false,则返回false;如果任务还没有执行,则无论mayInterruptIfRunning为true还是false,肯定返回true。
    • isCancelled方法表示任务是否被取消成功,如果在任务正常完成前被取消成功,则返回 true。
    • isDone方法表示任务是否已经完成,若任务完成,则返回true;
    • get()方法用来获取执行结果,这个方法会产生阻塞,会一直等到任务执行完毕才返回执行结果;
    • get(long timeout, TimeUnit unit)用来获取执行结果,如果在指定时间内,还没获取到结果,就直接抛TimeoutException。

    也就是说Future提供了三种功能:

      •   1)判断任务是否完成;
      •   2)能够中断任务;
      •   3)能够获取任务执行结果。
      因为Future是一个接口,所以是无法直接用来创建对象使用的,FutureTask是一个具体实现类。

    二、.FutureTask

     RunnableFuture继承了Runnable接口和Future接口,而FutureTask实现了RunnableFuture接口。所以它既可以作为Runnable被线程执行,又可以作为Future得到Callable的返回值。
      FutureTask是Future接口的一个实现类。
    所以可通过Excutor(线程池) 来执行,也可传递给Thread对象执行。 Executor框架利用FutureTask来完成异步任务,并可以用来进行任何潜在的耗时的计算。一般FutureTask多用于耗时的计算,主线程可以在完成自己的任务后,再去获取结果。

    三、实际案例

    例如现在通过调用一个方法从远程获取一些计算结果,如果是最传统的同步方式,代码大概如下:
      HashMap data = getDataFromRemote();
     我们将一直等待getDataFromRemote()的返回,然后才能继续后面的工作。这个函数是从远程获取数据的计算结果的,如果需要的时间很长,并且后面的那部分代码与这些数据没有有关系的话,阻塞在这里等待结果就会比较浪费时间。那么我们有什么办法改进呢?
     能够想到的办法就是调用函数后马上返回,然后继续向下执行,等需要用数据时再来用,或者说再来等待这个数据。具体实现起来有两种方式,一种是使用Future,一种是用回调
    使用Future
    Future<HashMap> future = getDataFromRemote2();
    //do something
    HashMap data = (HashMap) future.get();
    getDataFromRemote2()启动了对远程计算结果的获取,同时自己的线程还在继续处理,知道需要时再获取数据
    private Future<HashMap> getDataFromRemote2() {
        return threadpool.submit(new Callable<HashMap>() {
            public HashMap call() throws Exception {
                return getDataFromRemote()
            }
        });
    }
     
     
     
  • 相关阅读:
    HDU
    JQuery知识点总结
    html和css的使用方法以及样式
    面向对象五个基本原则
    【设计模式】【结构型模式】适配器模式
    为什么说Java中只有值传递?
    IntelliJ IDEA快捷键总结
    【设计模式】【创造型模式】单例模式
    【性能】定位现网环境中最耗费CPU的Java线程
    JavaWeb架构发展
  • 原文地址:https://www.cnblogs.com/hanxue112253/p/8489332.html
Copyright © 2011-2022 走看看