线程执行的时候,不想要等待怎么办。
多线程的异步处理,与同步处理相比,异步处理不用阻塞当前线程来等待处理完成,而是允许后续操作,直至其他线程处理完成,并回调通知该线程。
客户端与服务器端有 ajax 可以实现异步。
而我们 Java 也有 Future
接口实现同步。
如何使用?
查看官方文档
在JUC包下可以找到Future接口,我们需要掌握的就是CompletableFutrue
类,一般会使用它。
常用方法
-
没有返回值的异步操作
-
一个是直接运行线程,一个是通过Executor执行
-
-
-
又返回值的异步调用
-
一个是直接运行线程,一个是通过Executor执行
-
-
-
返回报错的信息
-
-
等待结果的返回
-
测试代码
没有返回值的异步回调
-
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()); } }
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()); } }
接下来的小节都是层层递进的。