Guava 的异步回调介绍

Guava 的异步回调

Guava是谷歌公司提供的 Java 扩展包,提供了一种异步回调的解决方案。

Guava 对 Java 的异步回调机制,做了以下的增强:

(1)引入了一个新的接口 ListenableFuture,继承了 Java 的 Future 接口,使得 Java 的 Future异步任务,在 Guava 中能被监控和获得非阻塞异步执行的结果。
(2)引入了一个新的接口 FutureCallback,这是一个独立的新接口。该接口的目的,是在异步任务执行完成后,根据异步结果,完成不同的回调处理,并且可以处理异步结果。

Guava 异步回调的流程如下:

第 1 步:实现 Java 的 Callable 接口,创建异步执行逻辑。还有一种情况,如果不需要返回值,异步执行逻辑也可以实现 Java 的 Runnable 接口。
第 2 步:创建 Guava 线程池。
第 3 步:将第 1 步创建的 Callable/Runnable 异步执行逻辑的实例,通过 submit 提交到 Guava线程池,从而获取 ListenableFuture 异步任务实例。
第 4 步:创建 FutureCallback 回调实例,通过 Futures.addCallback 将回调实例绑定到ListenableFuture 异步任务上。
完成以上四步,当 Callable/Runnable 异步执行逻辑完成后,就会回调异步回调实例FutureCallback 的回调方法onSuccess/onFailure

使用 Guava 实现泡茶喝的实践案例

代码实现:

public class GuavaFutureDemo {
    public static final int SLEEP_GAP = 500;

    public static String getCurThreadName() {
        return Thread.currentThread().getName();
    }

    static class HotWater implements Callable<Boolean> {
        @Override
        public Boolean call() throws Exception {
            try {
                System.out.println("洗好水壶");
                System.out.println("灌上凉水");
                System.out.println("放在火上");
                //睡一段时间 代表烧水
                Thread.sleep(SLEEP_GAP);
                System.out.println("水烧好了。");
            } catch (InterruptedException e) {
                e.printStackTrace();
                System.out.println("烧水 线程发生异常中断");
                return false;
            }
            System.out.println("烧水 线程完成");
            return true;
        }
    }

    static class Wash implements Callable<Boolean> {

        @Override
        public Boolean call() throws Exception {
            try {
                System.out.println("洗茶杯");
                System.out.println("洗水壶");
                //睡一段时间 洗水壶
                Thread.sleep(SLEEP_GAP);
                System.out.println("洗完了。");
            } catch (InterruptedException e) {
                e.printStackTrace();
                System.out.println("清洗 线程完成");
                return false;
            }
            System.out.println("清洗 线程结束");
            return true;
        }
    }

    static class MainJob implements Runnable {
        Boolean hOK = false;
        Boolean wOK = false;

        @Override
        public void run() {
            while (true) {
                try {
                    Thread.sleep(SLEEP_GAP);
                    System.out.println("等待中 看会儿书~~~");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                if (hOK && wOK) System.out.println("可以泡茶了,泡茶喝");

            }
        }
    }


    public static void main(String[] args) {
    	//创建一个新的线程实例,作为泡茶主线程
        MainJob mainJob = new MainJob();
        Thread mainThread = new Thread(mainJob);
        mainThread.setName("主线程");
        mainThread.start();
        //烧水和清洗的实例
        Callable<Boolean> hotCallable = new HotWater();
        Callable<Boolean> wCallable = new Wash();
        //创建 Java 线程池
        ExecutorService jpool = Executors.newFixedThreadPool(10);
        //包装 Java 线程池,构造 Guava 线程池
        ListeningExecutorService gpool = MoreExecutors.listeningDecorator(jpool);
        //提交烧水的业务逻辑实例,到 Guava 线程池获取异步任务
        ListenableFuture<Boolean> hFuture = gpool.submit(hotCallable);
        //绑定异步回调,烧水完成后,把喝水任务的 warterOk 标志设置为 true
        Futures.addCallback(hFuture, new FutureCallback<Boolean>() {
            @Override
            public void onSuccess(Boolean aBoolean) {
                if (aBoolean) mainJob.hOK = true;
            }

            @Override
            public void onFailure(Throwable throwable) {
                System.out.println("烧水失败 !");
            }
        });
        //提交清洗的业务逻辑实例,到 Guava 线程池获取异步任务
        ListenableFuture<Boolean> wFuture = gpool.submit(wCallable);
        //绑定任务执行完成后的回调逻辑到异步任务
        Futures.addCallback(wFuture, new FutureCallback<Boolean>() {
            @Override
            public void onSuccess(Boolean aBoolean) {
                if (aBoolean) mainJob.wOK = true;
            }

            @Override
            public void onFailure(Throwable throwable) {
                System.out.println("清洗失败 !");
            }
        });

    }
}

Guava 异步回调和 Java 的 FutureTask 异步回调,本质的不同在于:

  1. Guava 是非阻塞的异步回调,调用线程是不阻塞的,可以继续执行自己的业务逻辑。
  2. FutureTask 是阻塞的异步回调,调用线程是阻塞的,在获取异步结果的过程中,一直阻塞,等待异步线程返回结果。
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值