Future和改进版的ListenableFutrue

Future和改进版的ListenableFutrue


这里只是通过两个非常简单的示例,说明一下这两个的区别。

一、Future

我们知道,通过Callable和Future接口创建的线程,可以获得返回值,同时也可以声明抛出异常。这就比Runnable提升了很多。
我们先看下面的例子:

/**
 * @author lvxincao
 * @Description Future的demo示例
 * @Date 2021/1/26 17:08
 * @Version V1.0
 */
public class Myfuture {

    public static void main(String[] args) throws Exception{
        FutureTask<String> futureTask = new FutureTask<String>(new Callable<String>() {
            @Override
            public String call() throws Exception {
                System.out.println("子线程名称:" + Thread.currentThread().getName());
                TimeUnit.SECONDS.sleep(10);

                return "zhangsan";
            }
        });
        Thread thread = new Thread(futureTask);
        thread.start();
        System.out.println(futureTask.get());
        System.out.println("我是主线程:"+Thread.currentThread().getName());
    }
}

输出的结果如下:

子线程名称:Thread-0
zhangsan
我是主线程:main

这里我们看出一个问题,就是futureTask.get()获得返回值的方法,会阻塞主线程。这样的化,并不能充分发挥多线程的优势,更有些顺序执行的意思。那么怎么解决这个问题呢?
我们想,如果能够有一个线程来异步监听futureTask的结果,那么就不用阻塞主线程了。下面我们就看一下它的升级版:guava的ListenableFutrue。

二、ListenableFutrue

ListenableFuture和JDK原生Future最大的区别是前者做到了一个可以监听结果的Future。它可以监听异步执行的过程,执行完了,自动触发什么操作。除此之外,可以分别针对成功的情况,或者失败的情况做各种后续处理。
我们看下面的示例:

/**
 * @author lvxincao
 * @Description ListenableFutrues示例
 * @Date 2021/1/26 16:55
 * @Version V1.0
 */
public class MyListenableFutrue {

    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        ListenableFutureTask<String> stringListenableFutureTask = ListenableFutureTask.create(() -> {
            System.out.println("子线程名称:" + Thread.currentThread().getName());
            TimeUnit.SECONDS.sleep(10);
            return "zhangsan";
        });
        Futures.addCallback(stringListenableFutureTask, new FutureCallback<String>() {
            @Override
            public void onSuccess(@Nullable String s) {
                System.out.println("成功:" + s);
            }

            @Override
            public void onFailure(Throwable throwable) {
                System.out.println("失败:");
            }
        }, Executors.newSingleThreadExecutor());
        executorService.submit(stringListenableFutureTask);
        System.out.println("我是主线程:" + Thread.currentThread().getName());
    }
}

运行结果如下:

我是主线程:main
子线程名称:pool-1-thread-1
成功:zhangsan

我们看到,这时并没有出现主线程阻塞的情况。虽然如此,ListenableFutrue仍然存在缺陷,首先,写起来代码比较复杂繁琐;第二,它并没有解决多个异步任务需要相互依赖的场景。这就需要我们的java8中的CompletableFuture,我们后续会再进行详细的分析。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值