异步回调

举报
多米诺的古牌 发表于 2021/09/29 22:14:23 2021/09/29
【摘要】 1.异步回调说到异步回调我们第一个想到的肯定是ajax技术,它是客户端和服务器之间的异步回调技术,而在java线程中也可以异步通信,就是Futrue技术。Futrue接口是对将来的某个事件进行建模,其通过CompletableFuture进行实现。CompletableFuture是Future接口的实现方法,是当两个或者多个线程试图调用complete方法的时候,只会有一个成功,并且其可以...

1.异步回调

说到异步回调我们第一个想到的肯定是ajax技术,它是客户端和服务器之间的异步回调技术,而在java线程中也可以异步通信,就是Futrue技术。

Futrue接口是对将来的某个事件进行建模,其通过CompletableFuture进行实现。

CompletableFuture是Future接口的实现方法,是当两个或者多个线程试图调用complete方法的时候,只会有一个成功,并且其可以执行异步方法,方法如下图:

public static CompletableFuture<Void> runAsync(Runnable runnable,
                                               Executor executor) {
    return asyncRunStage(screenExecutor(executor), runnable);
}

2.Futrue接口实现的异步回调

2.1 步骤

2.1.1 首先创建Futrue接口的实现类CompletableFuture,指定其泛型

2.1.2 异步执行,异步执行分为两种,一种是没有返回值的执行方法runAsync,一种是有返回值的执行方法supplyAsync

2.1.2.1 可以设置成功回调方法,在有返回值的supplyAsync方法返回后,如果成功进行相关业务操作;

2.1.2.3 可以设置失败回调方法,在有返回值的supplyAsync方法返回后,如果失败则进行获取异常,错误的返回结果等操作;

3.CompletableFuture实现类的使用

3.1没有返回值的runAsync异步回调方法

注:Void为void的包装器类可以作为CompletableFuture的泛型,表示没有返回值。

public static void main(String[] args) throws ExecutionException, InterruptedException {
    CompletableFuture<Void> completableFuture = CompletableFuture.runAsync(()->{
        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"runAsync void");
    });
    System.out.println("查看是否延迟执行。。。");
    completableFuture.get();//获取阻塞执行结果
}

执行结果:

查看是否延迟执行。。。
ForkJoinPool.commonPool-worker-9runAsync void

如果我们将延迟去掉后,我们会发现谁先来就谁先执行,符合异步操作。

public static void main(String[] args) throws ExecutionException, InterruptedException {
    CompletableFuture<Void> completableFuture = CompletableFuture.runAsync(()->{
        System.out.println(Thread.currentThread().getName()+"runAsync void");
    });
    
    completableFuture.get();//获取阻塞执行结果
    System.out.println("查看是否延迟执行。。。");
}

执行结果:

ForkJoinPool.commonPool-worker-9runAsync void
查看是否延迟执行。。。

3.2 有返回值的异步回调方法<U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)

可以看出参数是一个供给型回调函数Supplier<U> (有没参数,只有返回值),因此可以优化为CompletableFuture.supplyAsync(()-{return 根据前面的设定的泛型设置此处的返回值});,此处返回的为成功的回调。

public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier) {
    return asyncSupplyStage(asyncPool, supplier);
}
public interface Supplier<T> {

    /**
     * Gets a result.
     *
     * @return a result
     */
    T get();
}

列举一个栗子:设置好成功的回调方法和失败的回调方法,通过下面的代码我们观察下成功和失败的回调都是怎么展示的。

public static void main(String[] args) {
        CompletableFuture<Integer> completableFuture = CompletableFuture.supplyAsync(()->{
            System.out.println(Thread.currentThread().getName()+"supplyAsync Integer");
            //int i = 19/0;
            return 1024;
        });
        completableFuture.whenComplete((t,u)->{
            System.out.println("t= "+t);//正常的返回结果 t= 1024 u= null
            System.out.println("u= "+u);//错误的信息 t= null u= java.util.concurrent.CompletionException: java.lang.ArithmeticException: / by zero
        }).exceptionally((e)->{
            //打印堆栈信息
//            return e.printStackTrace();
            //打印详细信息
            System.out.println(e.getMessage());//java.lang.ArithmeticException: / by zero
            return 999;//可以获取错误的返回结果
        });
    }

3.2.1 成功的回调

成功的回调方法whenComplete中的参数是一个BiConsumer函数式接口参数,长得很像Consumer接口,是一个消费型函数式接口的变种类型(传入参数T,返回参数U,没有返回值),通过lambda表示的可以优化为.whenComplete((t,u)->{相关业务代码})。

public CompletableFuture<T> whenComplete(
    BiConsumer<? super T, ? super Throwable> action) {
    return uniWhenCompleteStage(null, action);
}
public interface BiConsumer<T, U> {

    /**
     * Performs this operation on the given arguments.
     *
     * @param t the first input argument
     * @param u the second input argument
     */
    void accept(T t, U u);

3.2.2 失败的回调

失败的回调方法exceptionally方法参数为Throwable异常类,Exception和Error都继承了该类,其用来定义所有可以作为异常被抛出来的类(很牛逼),而返回值则是自定义的CompletableFuture的泛型,所以通过lambda表达式简化操作为.exceptionally((异常类的参数)->{return CompletableFuture中自定义的泛型})。

public CompletableFuture<T> exceptionally(
    Function<Throwable, ? extends T> fn) {
    return uniExceptionallyStage(fn);
}
public interface Function<T, R> {

    /**
     * Applies this function to the given argument.
     *
     * @param t the function argument
     * @return the function result
     */
    R apply(T t);


【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。