CompareFuture来龙去脉

一、Future


我们说到于实现多线程编程的接口,有几种想法

  1. 实现Runnable接口
  2. 实现Callable接口
  3. 实现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方法,如果调用方法的时候没有返回值,则返回一个提前定义的数值。

 

posted @ 2023-03-15 20:25  冬日寻雾记  阅读(409)  评论(0)    收藏  举报