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()
            }
        });
    }
     
     
  • 相关阅读:
    监控里的主码流和子码流是什么意思
    监控硬盘容量计算
    一个能让你了解所有函数调用顺序的Android库
    电工选线
    oracle linux dtrace
    list all of the Oracle 12c hidden undocumented parameters
    Oracle Extended Tracing
    window 驱动开发
    win7 x64 dtrace
    How to Use Dtrace Tracing Ruby Executing
  • 原文地址:https://www.cnblogs.com/ITtangtang/p/3966484.html
Copyright © 2011-2022 走看看