Java多线程:Callable,Future,FutureTask

java

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()

}

});

}

 

 

参考资料: 

    Java并发编程:Callable、Future和FutureTask

以上是 Java多线程:Callable,Future,FutureTask 的全部内容, 来源链接: utcz.com/z/393948.html

回到顶部