笑了,面试官问我知不知道异步编程的Future。 (4)

简介: 笑了,面试官问我知不知道异步编程的Future。 (4)

可以看一下代码,非常的直观:


public class JDKThreadPoolExecutorTest {
    public static void main(String[] args) throws Exception {
        ListeningExecutorService executor = MoreExecutors.listeningDecorator(Executors.newCachedThreadPool());
        ListenableFuture<String> listenableFuture = executor.submit(() -> {
            System.out.println(Thread.currentThread().getName()+"-女神:我开始化妆了,好了我叫你。");
            TimeUnit.SECONDS.sleep(5);
            return "化妆完毕了。";
        });
        Futures.addCallback(listenableFuture, new FutureCallback<String>() {
            @Override
            public void onSuccess(@Nullable String result) {
                System.out.println(Thread.currentThread().getName()+"-future的内容:" + result);
            }
            @Override
            public void onFailure(Throwable t) {
                System.out.println(Thread.currentThread().getName()+"-女神放你鸽子了。");
                t.printStackTrace();
            }
        });
        System.out.println(Thread.currentThread().getName()+"-等女神化妆的时候可以干点自己的事情。");
        Thread.currentThread().join();
    }
}


有 onSuccess 方法和 onFailure 方法。


上面的程序输出结果为:


image.png


如果异步任务执行的时候抛出了异常,比如女神被她的男神约走了,异步任务改成这样:


ListenableFuture<String> listenableFuture = executor.submit(() -> {
            System.out.println(Thread.currentThread().getName() + "-女神:我开始化妆了,好了我叫你。");
            TimeUnit.SECONDS.sleep(5);
            throw new Exception("男神约我看电影,就不和你吃饭了。");
        });


最终的运行结果就是这样:



image.png


加强版的Future - CompletableFuture


第一小节讲的 Future 是 JDK 1.5 时代的产物:


image.png


可以把这个接口理解为一个任务的某个阶段。所以多个 CompletionStage 链接在一起就是一个任务链。前一个任务完成后,下一个任务就会自动触发。


CompletableFuture 里面的方法非常的多。


由于篇幅原因,我就只演示一个方法:


public class JDKThreadPoolExecutorTest {
    public static void main(String[] args) throws Exception {
        CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getName() + "-女神:我开始化妆了,好了我叫你。");
            try {
                TimeUnit.SECONDS.sleep(5);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "化妆完毕了。";
        });
        completableFuture.whenComplete((returnStr, exception) -> {
            if (exception == null) {
                System.out.println(Thread.currentThread().getName() + returnStr);
            } else {
                System.out.println(Thread.currentThread().getName() + "女神放你鸽子了。");
                exception.printStackTrace();
            }
        });
        System.out.println(Thread.currentThread().getName() + "-等女神化妆的时候可以干点自己的事情。");
        Thread.currentThread().join();
    }
}


该方法的执行结果如下:


image.png


这个方法在很多开源框架里面使用的还是非常的多的。


接下来主要看看 CompletableFuture 对于异常的处理。我觉得非常的优雅。


不需要 try-catch 代码块包裹,也不需要调用 Future.get() 才知道异常了,它提供了一个 handle 方法,可以处理上游异步任务中出现的异常:


public class JDKThreadPoolExecutorTest {
    public static void main(String[] args) throws Exception {
        CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getName() + "-女神:我开始化妆了,好了我叫你。");
            throw new RuntimeException("男神约我看电影了,我们下次再约吧,你是个好人。");
        }).handleAsync((result, exception) -> {
            if (exception != null) {
                System.out.println(Thread.currentThread().getName() + "-女神放你鸽子了!");
                return exception.getCause();
            } else {
                return result;
            }
        }).thenApplyAsync((returnStr) -> {
            System.out.println(Thread.currentThread().getName() + "-" + returnStr);
            return returnStr;
        });
        System.out.println(Thread.currentThread().getName() + "-等女神化妆的时候可以干点自己的事情。");
        Thread.currentThread().join();
    }
}


由于女神在化妆的时候,接到男神的电话约她看电影,就只能放你鸽子了。


所以,上面程序的输出结果如下:


image.png


image.png


最后说一句(求关注)


按照我的经验,女神约出来了你需要准备好回答一个问题:


你看我今天有什么不同?


首先这题就是一道送命题,回答到她预期的答案的概率非常的低。有可能她今天不一样的地方就是换了一个指甲油、换了一个美瞳、换了一个耳环之类的。


很明显,这些非常细节的地方我们很难发现。但是别怂。


先含情脉脉的认真的盯着她,花一分钟找答案,一分钟后没有找到答案,就说:


你每天都不一样,每天都比昨天更加美丽。


好了,才疏学浅,难免会有纰漏,如果你发现了错误的地方,还请你在后台留言指出来,我对其加以修改。


感谢您的阅读,我坚持原创,十分欢迎并感谢您的关注。


我是 why,一个被代码耽误的文学创作者,不是大佬,但是喜欢分享,是一个又暖又有料的四川好男人。


还有,重要的事情说三遍: 欢迎关注我呀。 欢迎关注我呀。 欢迎关注我呀。


目录
相关文章
|
3月前
|
安全 Java 数据库连接
Java面试题:解释Java内存模型的无锁编程支持,并讨论其优势和局限性,解释Java中的CompletableFuture的工作原理,并讨论其在异步编程中的应用
Java面试题:解释Java内存模型的无锁编程支持,并讨论其优势和局限性,解释Java中的CompletableFuture的工作原理,并讨论其在异步编程中的应用
28 0
|
前端开发 JavaScript
前端开发面试题—JavaScript回调函数与异步编程
今天分享一下我遇到的一个面试题,是关于JavaScript回调函数的问题,什么是JavaScript回调函数?
154 0
前端开发面试题—JavaScript回调函数与异步编程
|
Java
笑了,面试官问我知不知道异步编程的Future。 (3)
笑了,面试官问我知不知道异步编程的Future。 (3)
101 0
笑了,面试官问我知不知道异步编程的Future。 (3)
|
Java
笑了,面试官问我知不知道异步编程的Future。 (2)
笑了,面试官问我知不知道异步编程的Future。 (2)
147 0
笑了,面试官问我知不知道异步编程的Future。 (2)
|
Dubbo Java 应用服务中间件
笑了,面试官问我知不知道异步编程的Future。 (1)
笑了,面试官问我知不知道异步编程的Future。 (1)
94 0
笑了,面试官问我知不知道异步编程的Future。 (1)
|
消息中间件 Java 微服务
消息队列面试解析系列(六)- 异步编程妙用(下)
消息队列面试解析系列(六)- 异步编程妙用
166 0
|
2月前
|
存储 Java
【IO面试题 四】、介绍一下Java的序列化与反序列化
Java的序列化与反序列化允许对象通过实现Serializable接口转换成字节序列并存储或传输,之后可以通过ObjectInputStream和ObjectOutputStream的方法将这些字节序列恢复成对象。
|
14天前
|
算法 Java 数据中心
探讨面试常见问题雪花算法、时钟回拨问题,java中优雅的实现方式
【10月更文挑战第2天】在大数据量系统中,分布式ID生成是一个关键问题。为了保证在分布式环境下生成的ID唯一、有序且高效,业界提出了多种解决方案,其中雪花算法(Snowflake Algorithm)是一种广泛应用的分布式ID生成算法。本文将详细介绍雪花算法的原理、实现及其处理时钟回拨问题的方法,并提供Java代码示例。
35 2
|
18天前
|
JSON 安全 前端开发
第二次面试总结 - 宏汉科技 - Java后端开发
本文是作者对宏汉科技Java后端开发岗位的第二次面试总结,面试结果不理想,主要原因是Java基础知识掌握不牢固,文章详细列出了面试中被问到的技术问题及答案,包括字符串相关函数、抽象类与接口的区别、Java创建线程池的方式、回调函数、函数式接口、反射以及Java中的集合等。
21 0
|
2月前
|
XML 存储 JSON
【IO面试题 六】、 除了Java自带的序列化之外,你还了解哪些序列化工具?
除了Java自带的序列化,常见的序列化工具还包括JSON(如jackson、gson、fastjson)、Protobuf、Thrift和Avro,各具特点,适用于不同的应用场景和性能需求。