CompareFuture来龙去脉
一、Future
我们说到于实现多线程编程的接口,有几种想法
- 实现Runnable接口
- 实现Callable接口
- 实现Future接口和FutureTask实现类
如果我们要求多线程、有返回值、并且可以异步操作,怎么实现呢
那么我们分别来看三个接口的特点
1.Runnable接口、Callable接口和Future接口
两者的区别是Runnable没有返回值,Callable有返回值,我们实现两个接口可以看到一个是void一个是String

但是两者都不能异步执行,而Future接口则是用来获取异步执行的信息
2.RunnableFurther接口
我们查看Runnable接口,发现它的Subinterfaces中有一个RunnableFurther接口,这个接口融合了Runnable和Further的特点,但是没有返回值。
然而,这个接口支持构造注入,我们将Callable对象注入,就完成了我们的条件
那么这个接口有什么优点呢:
它能够和线程池结合,实现异步多线程处理,并且有返回值,便于我们管理
然而,它也有一缺点:
我们来看这一段代码
public static void main(String[] args) throws ExecutionException, InterruptedException { FutureTask<String> futureTask = new FutureTask<String>(() -> { System.out.println("....."); try{ TimeUnit.SECONDS.sleep(5); }catch (InterruptedException e){ e.printStackTrace(); } return "over"; }); Thread t1 = new Thread(futureTask, "t1"); t1.start(); System.out.println(futureTask.get()); System.out.println("123"); }
当get的时候,异步并没有做完任务,get就会持续等待,阻塞线程,我们可以看到123在拿到返回值之后才能执行输出,
当然,我们可以加上isDone()的方法来轮询判断是否结束,但这样非常消耗cpu资源。
因此我们可以看到此接口对获取返回值并不友好
二、CompareFuture
因此,在JDK8中,CompareFuture雷应运而生。
在CompareFuture提供了一种观察者模式类似的机制,可以让任务执行完成后通知监听方
我们可以看到它实现了Future接口

类提供了两大类被方法
- runAsync 无返回值,可以和线程池配合,如果参数只有一个Runnable类,则调用默认线程池
- supplyAsync 有返回值,供给型,同上
与Further的get相比CompareFuture提供了join()方法,可以不阻塞队列的情况下,获取线程的返回值,同时提供了一个getNow方法,如果调用方法的时候没有返回值,则返回一个提前定义的数值。

浙公网安备 33010602011771号