深入了解JavaPromise:从多方面阐述

一、Promise的概念

Promise就是一种对异步操作结果的规范,类似于“保证书”,保证异步操作在未来一定会有一个返回值或异常抛出。

常见的Promise的状态有三种:Pending(进行中)、Resolved(已成功完成)、Rejected(已失败)。

public interface Promise extends Future {
    <U> Promise thenApply(Function<? super V, ? extends U> fn);
    <U> Promise<U> thenCompose(Function<? super V, ? extends CompletionStage<? extends U>> fn);
    Promise<V> exceptionally(Function<Throwable, ? extends V> fn);
    Promise<V> whenComplete(BiConsumer<? super V, ? super Throwable> action);
    Promise<V> whenCompleteAsync(BiConsumer<? super V, ? super Throwable> action);
}

JavaPromise就是在java.util.concurrent.Future的基础上分析封装出来的Promise实现。

下面我们就从不同的角度来深入了解JavaPromise的相关知识。

二、使用JavaPromise实现异步任务

在多线程编程中,异步任务非常常见,可以通过JavaPromise轻松实现异步任务操作。

例如下面的代码:我们创建一个简单的异步任务,该任务在1秒钟后会返回一个结果。

Promise<String> promise = CompletableFuture.supplyAsync(() -> {
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            throw new IllegalStateException(e);
        }
        return "异步任务已完成";
});

注意:以上代码中的supplyAsync方法创建了异步任务供后续调用使用。

三、JavaPromise中的thenApply方法

JavaPromise的thenApply方法可以将一个Promise实例转换成另一个Promise实例,并可以在转换的同时对得到的结果进行一些处理。

例如下面的代码:我们创建一个简单的异步任务,该任务在1秒钟后会返回一个结果。利用thenApply方法我们可以对结果进行处理。

Promise<String> promise = CompletableFuture.supplyAsync(() -> {
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                throw new IllegalStateException(e);
            }
            return "a";
        })
        .thenApply(s -> s + "b")
        .thenApply(s -> s + "c");

通过thenApply方法,我们可以将获取的结果转为另一个Promise,并对其进行处理。

四、JavaPromise中的thenCompose方法

thenCompose方法也是将一个Promise实例转换成另一个Promise实例,不同的是转换后的Promise是一个嵌套的Promise,可以一步步的对多个Promise进行处理。

例如下面的代码:我们创建了两个简单的异步任务,第二个任务需要第一个任务的结果作为输入。因此我们需要以thenCompose的形式,嵌套执行两个异步任务。

Promise<String> promise = CompletableFuture.supplyAsync(() -> {
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                throw new IllegalStateException(e);
            }
            return "a";
        })
        .thenCompose(s -> CompletableFuture.supplyAsync(() -> {
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                throw new IllegalStateException(e);
            }
            return s + "b";
        }));

注意:以上代码中第二个异步任务需要调用第一个任务的结果作为输入。

五、JavaPromise中的exceptionally方法

exceptionally方法用于在异步任务执行过程中现有异常,或任务失败时,提供一个备用值或者执行回调函数。

例如下面的代码:我们创建了一个简单的异步任务,该任务会随机抛出异常。为了避免程序抛出异常后无法继续执行下去,我们使用exceptionally方法对异常进行处理,并在处理时提供一个备用值。

Promise<String> promise = CompletableFuture.supplyAsync(() -> {
            Random random = new Random();
            if (random.nextBoolean()) {
                throw new RuntimeException("随机异常");
            }
            return "正常执行完成";
        })
        .exceptionally(ex -> "备用值");

在以上代码中,发生异常时,exceptionally方法会提供一个备用值。

六、JavaPromise中的whenComplete方法

whenComplete方法与exceptionally方法类似,也是当异步任务执行过程中发生异常时提供一个备用值或者执行回调函数的方法。

不同的是,whenComplete方法无论任务是否执行成功或失败都会得到执行。而且还可以在执行回调函数时继续对Future的操作。

例如下面的代码:我们创建一个简单的异步任务,当任务在1秒钟后完成时,根据随机值抛出异常。在异常发生时,我们将对异常进行处理,并继续异步操作。

Promise<String> promise = CompletableFuture.supplyAsync(() -> {
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                throw new IllegalStateException(e);
            }
            Random random = new Random();
            if (random.nextBoolean()) {
                throw new RuntimeException("随机异常");
            }
            return "正常执行完成";
        })
        .whenComplete((s, ex) -> {
            if (ex != null) {
                System.out.println("发生了异常:" + ex.getMessage());
            }
            System.out.println("异步任务已完成:" + s);
        });

七、JavaPromise中的whenCompleteAsync方法

whenCompleteAsync方法与whenComplete方法类似,也是当异步任务执行过程中发生异常时提供一个备用值或者执行回调函数的方法。

不同的是,whenCompleteAsync方法提供了异步执行回调函数的方式。

例如下面的代码:我们创建一个简单的异步任务,在1秒钟后随机抛出异常。在异常发生时,我们将对异常进行处理,并在回调处理中进行日志记录。并且在处理日志时,我们使用了whenCompleteAsync方法进行异步日志记录操作。

Executors.newSingleThreadExecutor().submit(() -> {
            Promise<String> promise = CompletableFuture.supplyAsync(() -> {
                        try {
                            TimeUnit.SECONDS.sleep(1);
                        } catch (InterruptedException e) {
                            throw new IllegalStateException(e);
                        }
                        Random random = new Random();
                        if (random.nextBoolean()) {
                            throw new RuntimeException("随机异常");
                        }
                        return "正常执行完成";
                    });
            promise.whenCompleteAsync((s, ex) -> {
                if (ex != null) {
                    System.out.println("发生了异常:" + ex.getMessage());
                }
                Executors.newSingleThreadExecutor().submit(() -> {
                    System.out.println("日志输出:" + System.currentTimeMillis());
                });
            });
        });

在该代码中,我们将日志记录异步操作通过whenCompleteAsync方法进行了处理。

以上就是对JavaPromise的介绍,通过以上几点我们可以看出,JavaPromise是Java8中新增的异步编程技术,它可以轻松实现异步操作,并提供了灵活的异步操作方式与回调处理机制。

原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/286706.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
小蓝小蓝
上一篇 2024-12-23 03:48
下一篇 2024-12-23 03:48

相关推荐

  • Python取较大值的多方面

    Python是一款流行的编程语言,广泛应用于数据分析、科学计算、Web开发等领域。作为一名全能开发工程师,了解Python的取较大值方法非常必要。本文将从多个方面对Python取较…

    编程 2025-04-27
  • 深入解析Vue3 defineExpose

    Vue 3在开发过程中引入了新的API `defineExpose`。在以前的版本中,我们经常使用 `$attrs` 和` $listeners` 实现父组件与子组件之间的通信,但…

    编程 2025-04-25
  • 深入理解byte转int

    一、字节与比特 在讨论byte转int之前,我们需要了解字节和比特的概念。字节是计算机存储单位的一种,通常表示8个比特(bit),即1字节=8比特。比特是计算机中最小的数据单位,是…

    编程 2025-04-25
  • 深入理解Flutter StreamBuilder

    一、什么是Flutter StreamBuilder? Flutter StreamBuilder是Flutter框架中的一个内置小部件,它可以监测数据流(Stream)中数据的变…

    编程 2025-04-25
  • 深入探讨OpenCV版本

    OpenCV是一个用于计算机视觉应用程序的开源库。它是由英特尔公司创建的,现已由Willow Garage管理。OpenCV旨在提供一个易于使用的计算机视觉和机器学习基础架构,以实…

    编程 2025-04-25
  • 深入了解scala-maven-plugin

    一、简介 Scala-maven-plugin 是一个创造和管理 Scala 项目的maven插件,它可以自动生成基本项目结构、依赖配置、Scala文件等。使用它可以使我们专注于代…

    编程 2025-04-25
  • 深入了解LaTeX的脚注(latexfootnote)

    一、基本介绍 LaTeX作为一种排版软件,具有各种各样的功能,其中脚注(footnote)是一个十分重要的功能之一。在LaTeX中,脚注是用命令latexfootnote来实现的。…

    编程 2025-04-25
  • 深入剖析MapStruct未生成实现类问题

    一、MapStruct简介 MapStruct是一个Java bean映射器,它通过注解和代码生成来在Java bean之间转换成本类代码,实现类型安全,简单而不失灵活。 作为一个…

    编程 2025-04-25
  • 深入了解Python包

    一、包的概念 Python中一个程序就是一个模块,而一个模块可以引入另一个模块,这样就形成了包。包就是有多个模块组成的一个大模块,也可以看做是一个文件夹。包可以有效地组织代码和数据…

    编程 2025-04-25
  • 深入理解Python字符串r

    一、r字符串的基本概念 r字符串(raw字符串)是指在Python中,以字母r为前缀的字符串。r字符串中的反斜杠(\)不会被转义,而是被当作普通字符处理,这使得r字符串可以非常方便…

    编程 2025-04-25

发表回复

登录后才能评论