网站架构的优化,企业管理系统哪个好,joomla可以做预订类网站吗,恩施网页定制文章目录 1. 简介#xff1a;2. 比较1、传统方式2、使用CompletableFuture#xff1a;异步执行返回值 3、组合处理#xff1a;anyOfallof : 4. 异步回调#xff1a;thenAcceptthenApplywhenComplete等同于 thenAccepthandel()等同于thenApply 5. 常用方法#xff1a;1、su… 文章目录 1. 简介2. 比较1、传统方式2、使用CompletableFuture异步执行返回值 3、组合处理anyOfallof : 4. 异步回调thenAcceptthenApplywhenComplete等同于 thenAccepthandel()等同于thenApply 5. 常用方法1、supplyAsync2、runAsync3、then*4、then*Async5、thenApply6、thenAccept7、thenRun8、thenCompose9、thenCombine10、runAfterEither11、runAfterBoth12、get()13、V get(long timeout, TimeUnit unit)14、T getNow(T valueIfAbsent)15、whenComplete16、exceptionally17、complete18、cancel19、allOf20、anyOf 1. 简介
CompletableFuture,它其实是JDK8提供出来的它是一种基于future异步编程的实现1、以前我们执行一个异步任务想要获得这个任务的返回值的时候就得通过这个future加callable这种传统方式来进行实现当我们要获得返回值的时候就去调用这个future task 的get方法当我们去调用get方法呢会阻塞所以像以前这种传统的异步编程并且要获的返回结果进行处理这种方式实现起来非常的麻烦并且要获的返回值会阻塞后面的代码。2、而当CompletableFuture来进行异步任务的话并且我们要拿到这个返回值进行处理也可以异步的方式而不会阻塞后面的代码3、CompletableFuture提供了组合处理比如我们有多个异步任务那么这多个异步任务中我想拿到里面最快的这一个在我们以前传统的异步编程当中实现起来非常麻烦但是通过 CompletableFuture是非常的简单的如果说我们想在这多个异步任务当中全部执行完成之后想去执行一些其他的在之前实现也非常麻烦此时就可以通过CompletableFuture来实现是非常的简单的4.还支持异步回调我们想在一个异步任务执行完成之后去执行另一个异步任务在以前我们必须对第一个任务进行“JOIN等待等第一个任务完成了之后再去执行第二任务或者把第二个任务嵌套在第一个任务内当第一个任务执行完成之后再去执行第二个任务但是这种嵌套方式会出现我们所谓的”回调地狱“也就是说如果你的异步任务非常的多并且都希望按照顺序一个一个去执行的话你需要每一个嵌套在上一个当中这样代码的可阅读性维护性都是非常差那我们通过CompletableFuture它所提供的这种异步回调实现起来是非常简洁的2. 比较
1、传统方式
package org.example;import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;/*** ClassName CompletableFutureTest* Author JS* Date 2024-05-15 23:30* Version 1.0**/
public class CompletableFutureTest {public static void main(String[] args) throws ExecutionException, InterruptedException {FutureTaskString futureTask new FutureTask(new CallableString() {Overridepublic String call() throws Exception {Thread.sleep(2000);return futureTask1执行完成;}});new Thread(futureTask).start();//get() 方法的作用是以阻塞的方式获取任务执行结果System.out.println(futureTask.get());System.out.println(TODO....);}
} 2、使用CompletableFuture
异步执行
runAsync()方法执行任务是没有返回值的supplyAsync() 方法执行任务则支持返回值
package org.example;import java.util.concurrent.CompletableFuture;/*** ClassName CompletableFutureDemo* Author lenovo* Date 2024-05-15 23:45* Version 1.0**/
public class CompletableFutureDemo {public static void main(String[] args) {CompletableFuture future1 CompletableFuture.runAsync(() - {System.out.println(执行没有返回值的任务);});CompletableFutureString future2 CompletableFuture.supplyAsync(() - {return 执行有返回的任务;});System.out.println(future2.join());}
}返回值
get()方法抛出 (InterruptedException、ExecutionException) 检查时异常程序必须处理join() 方法只抛出运行时异常程序可不做处理 3、组合处理
anyOf 返回跑的最快的那个future。最快的如果异常都玩完allof 全部并行执行执行完之后再去执行我们所需要的业务逻辑如果需要获得返回值需要配合thenApply异常会抛出不影响其他任务
anyOf
package org.example;import java.util.concurrent.CompletableFuture;/*** ClassName CompletableFutureDemo2* Author lenovo* Date 2024-05-15 23:52* Version 1.0**/
public class CompletableFutureDemo2 {public static void main(String[] args) {CompletableFutureString future1 CompletableFuture.supplyAsync(() - 朋友小王去你家送药);CompletableFutureString future2 CompletableFuture.supplyAsync(() - 朋友小去你家送药);CompletableFutureObject anyFutures CompletableFuture.anyOf(future1, future2);System.out.println(anyFutures.join());}
} 其实这种就可以运用在我们异步任务当中有多个备选方案比如我们请求第三方接口那么这第三方接口呢他提供l多个线路那这几个线路在某个时间段之内不确定谁更快那么我们就可以将这几个线路都通过 CompletableFuture 来进行异步请求然后再通过anyOf 拿到请求最快的那一个
allof :
package org.example;import java.util.concurrent.CompletableFuture;/*** ClassName CompletableFutureDemo3* Author lenovo* Date 2024-05-15 23:52* Version 1.0**/
public class CompletableFutureDemo3 {public static void main(String[] args) {CompletableFutureString future1 CompletableFuture.supplyAsync(() - 朋友小王去你家送药 );CompletableFutureString future2 CompletableFuture.supplyAsync(() - 朋友小去你家送药);CompletableFutureObject anyFutures CompletableFuture.allof(future1, future2).thenApply(res-{return future1.join()future2.join();//todo...执行我们所需要的业务逻辑代码});System.out.println(anyFutures.join());}
} 如果你想在多个异步任务执行完成之后来去执行一些业务逻辑的话那么就可以通过allof同样的传入多个futureallof的参数是一个可变长度的数组然后再结合 thenApply 这个方法来进行处理那在这个方法体当中我们就可以将 future1 和 future2 进行 join等待他们处理完成之后我们就可在后面执行我们所需要的业务逻辑代码这种逻辑功能比较适用于多个任务都需要并行的去执行但是呢要拿到他们每个任务的结果比方说我们在注册 验证的时候首先判断它的用户名是否被注册、手机号码是否被注册、手机验证码是否正确如果这几项都没有问题的话我们再去执行注册相关的业务代码。注意 allof出现异常不影响其他任务所以说可以针对每一个future进行try-catch 捕捉他们的异常如果非核心的future 他出现了异常我们也可以考虑继续执行我们的核心业务
4. 异步回调 whenComplete() 没有返回值且返回的 CompletableFuture 为任务结果而非回调结果 handle() 有返回值,且返回的CompletableFuture 为回调结果
他们两个出现异常不会中断 throwable 参数会接受前面的任务的异常异常会通过get抛出到主线程 链式处理 thenRun(Runnable runnable): 对异步任务的结果进行操作不能传入参也没有返回值 thenAccept(Consumer consumer):可传入参数 thenApply(Function function):可传入参数并返回结果
他们三个出现异常后面的任务会中断处理任务中感知不到异常异常会通过get抛出到主线程
thenAccept
package org.example;import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;/*** ClassName CompletableFutureTest2* Author lenovo* Date 2024-05-16 0:25* Version 1.0**/
public class CompletableFutureTest2 {public static void main(String[] args) throws ExecutionException, InterruptedException {CompletableFuture future2 CompletableFuture.supplyAsync(() - 5).thenAccept(result - {System.out.println(任务执行结果 result * 3);}).thenAccept(result - {System.out.println(任务执行完成);});}}thenApply
package org.example;import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;/*** ClassName CompletableFutureTest2* Author lenovo* Date 2024-05-16 0:35* Version 1.0**/
public class CompletableFutureTest3 {public static void main(String[] args) throws ExecutionException, InterruptedException {CompletableFuture future3 CompletableFuture.supplyAsync(() - 5).thenApply(result - result * 3).thenApply(result - result 3);System.out.println(future3:future3.join());}}whenComplete等同于 thenAccept
package org.example;import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;/*** ClassName CompletableFutureTest2* Author lenovo* Date 2024-05-16 0:25* Version 1.0**/
public class CompletableFutureTest4 {public static void main(String[] args) {CompletableFutureInteger future1 CompletableFuture.supplyAsync(() - {System.out.println(111);return 444;});CompletableFutureInteger future1Callback future1.whenComplete((result, throwable)-{System.out.println(222);}).whenComplete((result,throwable) - {System.out.println(333);});System.out.println(future1Callback.join());}}handel()等同于thenApply
package org.example;import java.util.concurrent.CompletableFuture;/*** ClassName CompletableFutureTest2* Author lenovo* Date 2024-05-16 0:44* Version 1.0**/
public class CompletableFutureTest5 {public static void main(String[] args) {CompletableFutureString future2 CompletableFuture.supplyAsync(()- {return返回任务结果;});CompletableFutureString future2Callback future2.handle((result, throwable) -{return返回任务结果;});System.out.println(future2Callback.join());}}5. 常用方法
1、supplyAsync
异步执行任务任务有返回值
package com.Js;import java.util.concurrent.*;
import java.util.function.Function;
import java.util.function.Supplier;public class Main {public static void main(String[] args) throws ExecutionException, InterruptedException {ExecutorService executorService Executors.newFixedThreadPool(10);CompletableFutureString task CompletableFuture.supplyAsync(() - {System.out.println(Thread.currentThread().getName());return Hello;}, executorService);}private static void sleep(int i) {try {TimeUnit.SECONDS.sleep(i);} catch (InterruptedException e) {System.out.println(e);e.printStackTrace();}}
}2、runAsync
异步执行任务任务没有返回值
package com.Js;import java.util.concurrent.*;public class Main {public static void main(String[] args) throws ExecutionException, InterruptedException {ExecutorService executorService Executors.newFixedThreadPool(10);CompletableFutureVoid task CompletableFuture.runAsync(() - {System.out.println(Thread.currentThread().getName());}, executorService);}private static void sleep(int i) {try {TimeUnit.SECONDS.sleep(i);} catch (InterruptedException e) {System.out.println(e);e.printStackTrace();}}
}3、then* 功能前一个异步任务执行完然后执行本任务 当前执行thenApply()方法的线程来负责执行本任务比如main线程但是如果前一个异步任务还没执行完那么main线程就不能执行本任务了得等前一个任务执行完后才能执行本任务这个时候就会在执行前一个任务的线程上执行本任务这样才能保证执行顺序
package com.Js;import java.util.concurrent.*;
import java.util.function.Function;
import java.util.function.Supplier;public class Main {public static void main(String[] args) throws ExecutionException, InterruptedException {ExecutorService executorService Executors.newFixedThreadPool(10);SupplierString taskA () - {System.out.println(1: Thread.currentThread().getName());return Hello;};FunctionString, String taskB s - {System.out.println(2: Thread.currentThread().getName());return s World;};CompletableFutureString future1 CompletableFuture.supplyAsync(taskA, executorService);sleep(1);future1.thenApply(taskB);System.out.println(haha);// ...}private static void sleep(int i) {try {TimeUnit.SECONDS.sleep(i);} catch (InterruptedException e) {e.printStackTrace();}}
}4、then*Async
会利用CompletableFuture中公共的ForkJoinPool来执行任务
5、thenApply
任务类型Function? super T,? extends U fn有入参有返回值
6、thenAccept
任务类型Consumer? super T action有入参无返回值
7、thenRun 任务类型Runnable action 无入参无返回值
8、thenCompose
任务类型Function? super T, ? extends CompletionStage fn有入参有返回值返回值类型只能是CompletionStage
ExecutorService executorService Executors.newFixedThreadPool(10);CompletableFutureString future CompletableFuture.supplyAsync(() - {System.out.println(Thread.currentThread().getName());return Hello;}, executorService).thenCompose(s - CompletableFuture.supplyAsync(() - {System.out.println(Thread.currentThread().getName());return s World;})).thenCompose(s - CompletableFuture.supplyAsync(() - {System.out.println(Thread.currentThread().getName());return s !!!;}));System.out.println(future.get());按顺序执行两个并行任务
9、thenCombine 任务类型CompletionStage? extends U other, BiFunction? super T,? super U,? extends V fn 有两个入参 第一个参数为CompletionStage 第二个参数为具体要执行的任务认为类型为BiFunction有两个入参一个返回值 ExecutorService executorService Executors.newFixedThreadPool(10);CompletableFutureString futureA CompletableFuture.supplyAsync(() - {System.out.println(Thread.currentThread().getName());sleep(3);return Hello;}, executorService);CompletableFutureString futureB CompletableFuture.supplyAsync(() - {System.out.println(Thread.currentThread().getName());sleep(3);return World;}, executorService);CompletableFutureString result futureA.thenCombine(futureB, (resultA, resultB) - {System.out.println(Thread.currentThread().getName());return resultA resultB;});System.out.println(result.get()); 整合两个并行执行的任务结果
10、runAfterEither 两个任务中任意一个完成了就执行回调 package com.Js;import java.util.concurrent.*;
import java.util.function.Function;
import java.util.function.Supplier;public class Main {public static void main(String[] args) throws ExecutionException, InterruptedException {ExecutorService executorService Executors.newFixedThreadPool(10);CompletableFutureString task1 CompletableFuture.supplyAsync(() - {System.out.println(Thread.currentThread().getName());sleep(5);return Hello;}, executorService);CompletableFutureString task2 CompletableFuture.supplyAsync(() - {System.out.println(Thread.currentThread().getName());sleep(5);return World;}, executorService);task2.runAfterEither(task1, () - System.out.println(!!!));}private static void sleep(int i) {try {TimeUnit.SECONDS.sleep(i);} catch (InterruptedException e) {e.printStackTrace();}}
}11、runAfterBoth 两个任务都完成了才执行回调 package com.Js;import java.util.concurrent.*;
import java.util.function.Function;
import java.util.function.Supplier;public class Main {public static void main(String[] args) throws ExecutionException, InterruptedException {ExecutorService executorService Executors.newFixedThreadPool(10);CompletableFutureString task1 CompletableFuture.supplyAsync(() - {System.out.println(Thread.currentThread().getName());sleep(5);return Hello;}, executorService);CompletableFutureString task2 CompletableFuture.supplyAsync(() - {System.out.println(Thread.currentThread().getName());
// sleep(5);return World;}, executorService);task2.runAfterBoth(task1, () - System.out.println(!!!));}private static void sleep(int i) {try {TimeUnit.SECONDS.sleep(i);} catch (InterruptedException e) {e.printStackTrace();}}
}12、get()
阻塞等待结果
13、V get(long timeout, TimeUnit unit)
超时等待结果
14、T getNow(T valueIfAbsent)
立即获取结果如果任务还没完成则返回valueIfAbsent
15、whenComplete
入参为BiConsumer? super T, ? super Throwable action 任务正常结束第一个参数传入的是结果任务异常结束第二个参数传入的是异常 异常类型是CompletionException 没有返回值
16、exceptionally
入参为FunctionThrowable, ? extends T fn 入参为异常 异常类型是CompletionException 可以返回其他值如果任务没有出现异常则不会执行
17、complete
直接让任务完成
package com.Js;import java.util.concurrent.*;
import java.util.function.Function;
import java.util.function.Supplier;public class Main {public static void main(String[] args) throws ExecutionException, InterruptedException {ExecutorService executorService Executors.newFixedThreadPool(10);CompletableFutureString task1 CompletableFuture.supplyAsync(() - {System.out.println(Thread.currentThread().getName());sleep(5);return Hello;}, executorService);task1.complete(haha);System.out.println(task1.get());executorService.shutdown();}private static void sleep(int i) {try {TimeUnit.SECONDS.sleep(i);} catch (InterruptedException e) {e.printStackTrace();}}
}18、cancel 如果任务还没开始或正在执行则能取消设置取消标记为true package com.Js;import java.util.concurrent.*;
import java.util.function.Function;
import java.util.function.Supplier;public class Main {public static void main(String[] args) throws ExecutionException, InterruptedException {ExecutorService executorService Executors.newFixedThreadPool(10);CompletableFutureString task CompletableFuture.supplyAsync(() - {sleep(3);System.out.println(Thread.currentThread().getName());return Hello;}, executorService);sleep(1);task.cancel(false);System.out.println(task.get());}private static void sleep(int i) {try {TimeUnit.SECONDS.sleep(i);} catch (InterruptedException e) {System.out.println(e);e.printStackTrace();}}
}如果任务已经完成则设置取消标记为false
19、allOf 所有任务都执行完后才执行下一个任务 package com.Js;import java.util.concurrent.*;
import java.util.function.Function;
import java.util.function.Supplier;public class Main {public static void main(String[] args) throws ExecutionException, InterruptedException {ExecutorService executorService Executors.newFixedThreadPool(10);CompletableFutureString task1 CompletableFuture.supplyAsync(() - {System.out.println(Thread.currentThread().getName());sleep(5);return Hello;}, executorService);CompletableFutureString task2 CompletableFuture.supplyAsync(() - {System.out.println(Thread.currentThread().getName());return World;}, executorService);CompletableFuture.allOf(task1, task2).join();System.out.println(!!!);}private static void sleep(int i) {try {TimeUnit.SECONDS.sleep(i);} catch (InterruptedException e) {e.printStackTrace();}}
}20、anyOf 任意一个任务执行完就可以执行下一个任务了 package com.Js;import java.util.concurrent.*;
import java.util.function.Function;
import java.util.function.Supplier;public class Main {public static void main(String[] args) throws ExecutionException, InterruptedException {ExecutorService executorService Executors.newFixedThreadPool(10);CompletableFutureString task1 CompletableFuture.supplyAsync(() - {System.out.println(Thread.currentThread().getName());sleep(5);return Hello;}, executorService);CompletableFutureString task2 CompletableFuture.supplyAsync(() - {System.out.println(Thread.currentThread().getName());return World;}, executorService);CompletableFuture.anyOf(task1, task2).join();System.out.println(!!!);}private static void sleep(int i) {try {TimeUnit.SECONDS.sleep(i);} catch (InterruptedException e) {e.printStackTrace();}}
}