zoukankan      html  css  js  c++  java
  • 12、多线程的异步回调

    引用学习(狂神说)

    介绍

    线程执行的时候,不想要等待怎么办。

    多线程的异步处理,与同步处理相比,异步处理不用阻塞当前线程来等待处理完成,而是允许后续操作,直至其他线程处理完成,并回调通知该线程。

    客户端与服务器端有 ajax 可以实现异步。

    而我们 Java 也有 Future接口实现同步。

    如何使用?

    查看官方文档

    在JUC包下可以找到Future接口,我们需要掌握的就是CompletableFutrue类,一般会使用它。

    常用方法

    1. 没有返回值的异步操作

      • 一个是直接运行线程,一个是通过Executor执行

    2. 又返回值的异步调用

      • 一个是直接运行线程,一个是通过Executor执行

    3. 返回报错的信息

    4. 等待结果的返回

    测试代码

    没有返回值的异步回调

    • CompletableFuture.runAsync(),执行异步任务,没有返回值

    package com.zxh.future;
    
    import java.util.concurrent.CompletableFuture;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.TimeUnit;
    
    
    /**
     * 异步回调:CompletablFuture
     * 1、可以异步执行
     * 2、成功回调
     * 3、失败回调
     */
    public class Demo01 {
        public static void main(String[] args) throws ExecutionException, InterruptedException {
            // 没有返回值的异步回调
            // Void类,就是void关键字,没有返回值
            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("1111");
            completableFuture.get();    // 获取阻塞执行结果
    
        }
    }

    如果只是通过Thread创建线程,如果有上面的阻塞等待的情况,也会先输出111,但是无法自由控制,它是由CPU控制的。

    执行成功:有返回值的异步操作

    • CompletableFuture.supplyAsync(),执行异步任务,并且有返回值

    package com.zxh.future;
    
    import java.util.concurrent.CompletableFuture;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.TimeUnit;
    
    
    /**
     * 异步回调:CompletablFuture
     * 1、可以异步执行
     * 2、成功回调
     * 3、失败回调
     */
    public class Demo01 {
        public static void main(String[] args) throws ExecutionException, InterruptedException {
            /*
                有返回值的回调,supplyAsync():里面的参数是Suplier供给型函数接口,有输出,没有输入
              */
            CompletableFuture<Integer> completableFuture = CompletableFuture.supplyAsync(() -> {
                System.out.println(Thread.currentThread().getName() + "supplyAsync=> 有返回值");    // 表示执行了异步任务
                return 1024;    //直接返回 1024
            });
    
            /*
                BiConsumer:是消费型接口的改变版,可以传递2个参数 void accept(T t, U u);
                    这两个参数,t表示:正常的返回结果,u表示:错误信息
                exceptionally方法:参数为Function<Throwable, ? extends T> fn),可以有输入也可以有返回值
                    如果有错误就将错误输入,输出
                get()方法:获取异步回调返回的参数
             */
            System.out.println(completableFuture.whenComplete((t, u)->{
                System.out.println("t=>" + t);
                System.out.println("u=>" + u);
            }).exceptionally((e) -> {
                System.out.println(e.getMessage());
                return 500; // 可以获取到错误的返回值
            }).get());
    
        }
    }

    执行失败:模拟除数为0错误

    package com.zxh.future;
    
    import java.util.concurrent.CompletableFuture;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.TimeUnit;
    
    
    /**
     * 异步回调:CompletablFuture
     * 1、可以异步执行
     * 2、成功回调
     * 3、失败回调
     */
    public class Demo01 {
        public static void main(String[] args) throws ExecutionException, InterruptedException {
            /*
                有返回值的回调,supplyAsync():里面的参数是Suplier供给型函数接口,有输出,没有输入
              */
            CompletableFuture<Integer> completableFuture = CompletableFuture.supplyAsync(() -> {
                System.out.println(Thread.currentThread().getName() + "supplyAsync=> 有返回值");    // 表示执行了异步任务
                int i = 1/0;    // 制造异常
                return 1024;    //直接返回 1024
            });
    
            /*
                whenComplete(BiConsumer<? super T, ? super Throwable> action):
                    获取该线程的返回值和异常信息,第一个参数是返回值,第二个参数是异常信息
                    BiConsumer:是消费型接口的改变版,可以传递2个参数 void accept(T t, U u);
                        这两个参数,t表示:正常的返回结果,u表示:错误信息
                exceptionally(Function<Throwable, ? extends T> fn)):
                    参数为Function:可以有输入也可以有返回值
                    如果出现错误,将错误对象传入函数接口,输出错误,并自定义返回值
                get()方法:获取异步回调返回的参数
             */
            System.out.println(completableFuture.whenComplete((t, u)->{
                System.out.println("t=>" + t);  // 正常的返回结果
                System.out.println("u=>" + u);  // 错误信息
            }).exceptionally((e) -> {
                System.out.println(e.getMessage()); // 输出错误信息
                return 500; // 可以获取到错误的返回值
            }).get());
    
        }
    }

     接下来的小节都是层层递进的。

    致力于记录学习过程中的笔记,希望大家有所帮助(*^▽^*)!
  • 相关阅读:
    牡牛和牝牛
    卡特兰数 Catalan number
    Codeforces Round #633 (Div. 2)
    Codeforces Round #634 (Div. 3)
    陪审团
    线性DP
    AcWing 274. 移动服务
    Rust打印方法行号
    八.枚举与模式匹配
    七.结构体
  • 原文地址:https://www.cnblogs.com/zxhbk/p/13023925.html
Copyright © 2011-2022 走看看