Guava 的异步回调介绍

简介: 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 是阻塞的异步回调,调用线程是阻塞的,在获取异步结果的过程中,一直阻塞,等待异步线程返回结果。
目录
相关文章
|
Rust 安全 开发者
Rust之旅:打造并发布你的首个Rust库
本文将引导读者走进Rust的世界,从基础概念讲起,逐步深入到如何创建、测试、打包和发布自己的Rust库。通过实际操作,我们将理解Rust的独特之处,并学会如何分享自己的代码到Rust社区,从而为开源世界做出贡献。
|
前端开发 Java 应用服务中间件
解决跨域问题的8种方法,含网关、Nginx和SpringBoot~
解决跨域问题的8种方法,含网关、Nginx和SpringBoot~
2563 0
解决跨域问题的8种方法,含网关、Nginx和SpringBoot~
|
存储 缓存 负载均衡
《深入分布式缓存》之“关于Tair哪些事儿”
版权声明:本文为半吊子子全栈工匠(wireless_com,同公众号)原创文章,未经允许不得转载。
2446 0
|
算法 安全 Ubuntu
8 种 Java 内存溢出之八 -Kill process or sacrifice child
8 种 Java 内存溢出之八 -Kill process or sacrifice child
|
10月前
|
开发工具 git iOS开发
阿里同学都在用的开发环境和工具
本文主要介绍后端开发同学常用的工具以及开发环境搭建。
|
Linux 开发工具
centos7 中文乱码解决方法
centos7 中文乱码解决方法
688 1
|
开发工具 Android开发 git
解决Idea报错出现Git is not installed
解决Idea报错出现Git is not installed
4683 2
|
设计模式 开发者 Python
Python中循环依赖问题及其解决方案
循环依赖是 Python 开发中需要特别注意的问题。通过重新设计模块结构、延迟导入、依赖注入、利用 Python 的动态特性以及代码重构等方法,可以有效地解决循环依赖问题。这些策略不仅有助于提高代码的可维护性和可读性,还能避免潜在的运行时错误。在实际开发中,开发者应该根据具体情况选择合适的解决方案。
|
JavaScript API
若依没解构送post请求出现的bug,vue.runtime.esm.js:620 [Vue warn]: Error in mounted hook: “TypeError: (0 , _inde
若依没解构送post请求出现的bug,vue.runtime.esm.js:620 [Vue warn]: Error in mounted hook: “TypeError: (0 , _inde
|
应用服务中间件 nginx Windows
Windows修改nginx.conf配置文件然后重新加载报错
Windows修改nginx.conf配置文件然后重新加载报错
707 0

热门文章

最新文章