Java并发-Runnable、Callable、Future、Future Task

Runnable:

Runnable的代码非常简单,他是一个接口,且接口中只有一个方法,run(),创建一个类实现他,把一些费时操作写在其中,然后使用某个线程去执行该Runnable实现类即可实现多线程。

Callable:

Callable的代码也非常简单,不同的是他是一个泛型接口,call()函数返回的类型就是创建Callable传进来的V类型,Callable与Runnable的功能大致相同,项目中有些任务是需要异步(提交到线程池中)去执行,而主线程往往需要知道异步执行产生的结果,这时我们要怎么做?用Runnable是无法实现的,我们需要用Callable去实现。

Future:

public interface Future<V> {
     boolean cancel(boolean mayInterruptIfRunning);
     boolean isCancelled();
     boolean isDone();
     V get() throws InterruptedException,ExecutionException;
     V get(long timeOut,@NotNull TimeUnit unit) throws InterruptedException,ExecutionException,TimeoutException;        
}

Future是一个接口,定义了Future对于具体的Runnable或者Callable任务的执行结果进行取消、查询任务是否被取消,查询是否完成,获取结果、

Future的基本用法:

通过上面的代码并运行:

1、线程是属于异步计算模型,所以你不可能从别的线程中得到方法的返回值,这时候,我们就需要使用Future。

2、Future可以监视目标线程调用Call的情况,当你调用Future的get()方法以获得结果的时候,当前线程就开始阻塞,直接call方法结束返回结果。

3、Future引用对象指向的其实就是FutureTask。

总结:Future可以得到其他线程方法的返回值

FutureTask:

FutureTask的父类是RunnableFuture,而RunnableFuture继承了Runnable和Future两个接口

FutureTask的构造方法:

通过上面的构造函数,我们可以看到,

1、FutureTask最终都是执行Callable类型的任务。

2、如果构造函数参数是Runnable,会被Executors.callable方法转换为Callable类型

下面是Executors.callable方法。

最终返回的是一个RunnableAdapter实例。

继续看看RunnableAdapter的实例。

1、RunnableAdapter是一个FutureTask的一个静态内部类并且实现了Callable,也就是说RunnableAdapter是Callable的一个子类

2、call方法实现代码是,执行Runnable的run方法,并返回构造函数中传入的参数result。

FutureTask的总结:

FutureTask实现两个接口,分为是Future和Runnable,所以它既作为Runnable被线程执行,又可以作为Future得到Callable的返回值,这个组合使用的好处在哪里?

eg:假设有一个很费时逻辑需要计算并返回这个值,同时这个值又不是马上需要,就可以使用这个组合(FutureTask),用另一个线程去计算返回值,而当前线程在使用这个返回值的时候可以进行其他的操作,等到需要这个返回值的时候,再通过Future得到。

注意:通过Executor执行线程任务都是以Callable形式,如果传入Runnable都会转化为Callable。

通过new Thread(runnable),只能是Runnable子类形式

  

posted on 2018-08-13 19:04  zzzhouheng  阅读(342)  评论(0编辑  收藏  举报

导航