笑了,面试官问我知不知道异步编程的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,一个被代码耽误的文学创作者,不是大佬,但是喜欢分享,是一个又暖又有料的四川好男人。


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


目录
相关文章
|
6月前
|
安全 Java 数据库连接
Java面试题:解释Java内存模型的无锁编程支持,并讨论其优势和局限性,解释Java中的CompletableFuture的工作原理,并讨论其在异步编程中的应用
Java面试题:解释Java内存模型的无锁编程支持,并讨论其优势和局限性,解释Java中的CompletableFuture的工作原理,并讨论其在异步编程中的应用
33 0
|
前端开发 JavaScript
前端开发面试题—JavaScript回调函数与异步编程
今天分享一下我遇到的一个面试题,是关于JavaScript回调函数的问题,什么是JavaScript回调函数?
164 0
前端开发面试题—JavaScript回调函数与异步编程
|
Java
笑了,面试官问我知不知道异步编程的Future。 (3)
笑了,面试官问我知不知道异步编程的Future。 (3)
114 0
笑了,面试官问我知不知道异步编程的Future。 (3)
|
Java
笑了,面试官问我知不知道异步编程的Future。 (2)
笑了,面试官问我知不知道异步编程的Future。 (2)
155 0
笑了,面试官问我知不知道异步编程的Future。 (2)
|
Dubbo Java 应用服务中间件
笑了,面试官问我知不知道异步编程的Future。 (1)
笑了,面试官问我知不知道异步编程的Future。 (1)
108 0
笑了,面试官问我知不知道异步编程的Future。 (1)
|
消息中间件 Java 微服务
消息队列面试解析系列(六)- 异步编程妙用(下)
消息队列面试解析系列(六)- 异步编程妙用
172 0
|
5月前
|
存储 Java
【IO面试题 四】、介绍一下Java的序列化与反序列化
Java的序列化与反序列化允许对象通过实现Serializable接口转换成字节序列并存储或传输,之后可以通过ObjectInputStream和ObjectOutputStream的方法将这些字节序列恢复成对象。
|
2月前
|
存储 缓存 算法
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!
本文介绍了多线程环境下的几个关键概念,包括时间片、超线程、上下文切换及其影响因素,以及线程调度的两种方式——抢占式调度和协同式调度。文章还讨论了减少上下文切换次数以提高多线程程序效率的方法,如无锁并发编程、使用CAS算法等,并提出了合理的线程数量配置策略,以平衡CPU利用率和线程切换开销。
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!
|
2月前
|
存储 算法 Java
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
本文详解自旋锁的概念、优缺点、使用场景及Java实现。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
|
2月前
|
存储 缓存 Java
大厂面试必看!Java基本数据类型和包装类的那些坑
本文介绍了Java中的基本数据类型和包装类,包括整数类型、浮点数类型、字符类型和布尔类型。详细讲解了每种类型的特性和应用场景,并探讨了包装类的引入原因、装箱与拆箱机制以及缓存机制。最后总结了面试中常见的相关考点,帮助读者更好地理解和应对面试中的问题。
76 4

热门文章

最新文章