CompletableFuture
使用场景:
查询: 一个方法要返回A数据,但是A数据由B,C,D组成。其中C,D 查询需要依赖B数据的结果查询,为加快查询速度C,D并发执行, 这个时候可以用CompletableFuture解决。
public static void Test5() {
//线程池
ThreadPoolExecutor THREAD_POOL_EXECUTOR = new ThreadPoolExecutor(5, 16, 10, TimeUnit.SECONDS, new LinkedBlockingDeque<>(1000), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
ArrayList<String> A = new ArrayList<>();
// 创建异步执行任务:
CompletableFuture<String> B = CompletableFuture.supplyAsync(() -> {
A.add("B");
//B返回
return "B";
}, THREAD_POOL_EXECUTOR);
//thenApplyAsync:有返回值
//thenAcceptAsync:无返回值
CompletableFuture<String> C = B.thenApplyAsync((result) -> {
//这里需要B的结果做些操作
String c = result + "C";
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
A.add(c);
return c;
}, THREAD_POOL_EXECUTOR);
CompletableFuture<String> D = B.thenApplyAsync((result) -> {
//这里需要B的结果做些操作
String d = result + "D";
A.add(d);
return d;
}, THREAD_POOL_EXECUTOR);
try {
CompletableFuture.allOf(D, C).get();
System.out.println(A);
} catch (Exception e) {
e.printStackTrace();
}
}
//运行结果
//[B, BD, BC]
简单使用:
import java.util.ArrayList;
import java.util.concurrent.*;
public class Test {
private static final ThreadPoolExecutor THREAD_POOL_EXECUTOR = new ThreadPoolExecutor(5, 16, 10, TimeUnit.SECONDS, new LinkedBlockingDeque<>(1000), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
public static void main(String[] args) throws Exception {
// Test.Test1();
Test.Test5();
}
/**
* 常用:
* supplyAsync 创建带返回值的异步任务的
* runAsync 创建无返回值的异步任务的
*/
public static void Test1() {
CompletableFuture<String> infoFuture1 = CompletableFuture.supplyAsync(() -> {
//1、sku基本信息的获取 pms_sku_info
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "infoFuture1";
}, THREAD_POOL_EXECUTOR);
try {
// 等待返回
infoFuture1.get();
System.out.println(infoFuture1.get());
} catch (Exception e) {
e.printStackTrace();
}
CompletableFuture<Void> infoFuture2 = CompletableFuture.runAsync(() -> {
System.out.println("infoFuture2");
//1、sku基本信息的获取 pms_sku_info
}, THREAD_POOL_EXECUTOR);
}
/**
* 常用:
* thenApplyAsync 表示某个任务执行完成后执行的动作,即回调方法,会将该任务的执行结果即方法返回值作为入参传递到回调方法中,测试用例如下:
*/
public static void Test2() throws ExecutionException, InterruptedException {
// 创建异步执行任务:
CompletableFuture<Double> cf = CompletableFuture.supplyAsync(() -> {
System.out.println(Thread.currentThread() + " start job1,time->" + System.currentTimeMillis());
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
System.out.println(Thread.currentThread() + " exit job1,time->" + System.currentTimeMillis());
return 1.2;
}, THREAD_POOL_EXECUTOR);
//cf关联的异步任务的返回值作为方法入参,传入到thenApply的方法中
//thenApplyAsync这里实际创建了一个新的CompletableFuture实例
CompletableFuture<String> cf2 = cf.thenApplyAsync((result) -> {
System.out.println(Thread.currentThread() + " start job2,time->" + System.currentTimeMillis());
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
System.out.println(Thread.currentThread() + " exit job2,time->" + System.currentTimeMillis());
return "test:" + result;
}, THREAD_POOL_EXECUTOR);
System.out.println("main thread start cf.get(),time->" + System.currentTimeMillis());
//等待子任务执行完成
System.out.println("run result->" + cf.get());
System.out.println("main thread start cf2.get(),time->" + System.currentTimeMillis());
System.out.println("run result->" + cf2.get());
System.out.println("main thread exit,time->" + System.currentTimeMillis());
}
/**
* exceptionally
* exceptionally方法指定某个任务执行异常时执行的回调方法,会将抛出异常作为参数传递到回调方法中,
* 如果该任务正常执行则会exceptionally方法返回的CompletionStage的result就是该任务正常执行的结果,测试用例如下:
*
* @throws Exception
*/
public static void Test3() throws Exception {
// 创建异步执行任务:
CompletableFuture<Double> cf = CompletableFuture.supplyAsync(() -> {
System.out.println(Thread.currentThread() + "job1 start,time->" + System.currentTimeMillis());
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
if (true) {
throw new RuntimeException("test");
} else {
System.out.println(Thread.currentThread() + "job1 exit,time->" + System.currentTimeMillis());
return 1.2;
}
}, THREAD_POOL_EXECUTOR);
//cf执行异常时,将抛出的异常作为入参传递给回调方法
CompletableFuture<Double> cf2 = cf.exceptionally((param) -> {
System.out.println(Thread.currentThread() + " start,time->" + System.currentTimeMillis());
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
System.out.println("error stack trace->");
param.printStackTrace();
System.out.println(Thread.currentThread() + " exit,time->" + System.currentTimeMillis());
return -1.1;
});
//cf正常执行时执行的逻辑,如果执行异常则不调用此逻辑
CompletableFuture cf3 = cf.thenAccept((param) -> {
System.out.println(Thread.currentThread() + "job2 start,time->" + System.currentTimeMillis());
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
System.out.println("param->" + param);
System.out.println(Thread.currentThread() + "job2 exit,time->" + System.currentTimeMillis());
});
System.out.println("main thread start,time->" + System.currentTimeMillis());
//等待子任务执行完成,此处无论是job2和job3都可以实现job2退出,主线程才退出,如果是cf,则主线程不会等待job2执行完成自动退出了
//cf2.get时,没有异常,但是依然有返回值,就是cf的返回值
System.out.println("run result->" + cf2.get());
System.out.println("main thread exit,time->" + System.currentTimeMillis());
}
/**
* allOf返回的CompletableFuture是多个任务都执行完成后才会执行,只有有一个任务执行异常,则返回的CompletableFuture执行get方法时会抛出异常,如果都是正常执行,则get返回null。
*/
public static void Test4() throws Exception {
// 创建异步执行任务:
CompletableFuture<Double> cf = CompletableFuture.supplyAsync(() -> {
System.out.println(Thread.currentThread() + " start job1,time->" + System.currentTimeMillis());
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
System.out.println(Thread.currentThread() + " exit job1,time->" + System.currentTimeMillis());
return 1.2;
});
CompletableFuture<Double> cf2 = CompletableFuture.supplyAsync(() -> {
System.out.println(Thread.currentThread() + " start job2,time->" + System.currentTimeMillis());
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
}
System.out.println(Thread.currentThread() + " exit job2,time->" + System.currentTimeMillis());
return 3.2;
});
CompletableFuture<Double> cf3 = CompletableFuture.supplyAsync(() -> {
System.out.println(Thread.currentThread() + " start job3,time->" + System.currentTimeMillis());
try {
Thread.sleep(1300);
} catch (InterruptedException e) {
}
//throw new RuntimeException("test");
System.out.println(Thread.currentThread() + " exit job3,time->" + System.currentTimeMillis());
return 2.2;
});
//allof等待所有任务执行完成才执行cf4,如果有一个任务异常终止,则cf4.get时会抛出异常,都是正常执行,cf4.get返回null
//anyOf是只有一个任务执行完成,无论是正常执行或者执行异常,都会执行cf4,cf4.get的结果就是已执行完成的任务的执行结果
CompletableFuture cf4 = CompletableFuture.allOf(cf, cf2, cf3).whenComplete((a, b) -> {
if (b != null) {
System.out.println("error stack trace->");
b.printStackTrace();
} else {
System.out.println("run succ,result->" + a);
}
});
System.out.println("main thread start cf4.get(),time->" + System.currentTimeMillis());
//等待子任务执行完成
System.out.println("cf4 run result->" + cf4.get());
System.out.println("main thread exit,time->" + System.currentTimeMillis());
}
public static void Test5() {
//线程池
ThreadPoolExecutor THREAD_POOL_EXECUTOR = new ThreadPoolExecutor(5, 16, 10, TimeUnit.SECONDS, new LinkedBlockingDeque<>(1000), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
ArrayList<String> A = new ArrayList<>();
// 创建异步执行任务:
CompletableFuture<String> B = CompletableFuture.supplyAsync(() -> {
A.add("B");
//B返回
return "B";
}, THREAD_POOL_EXECUTOR);
//thenApplyAsync:有返回值
//thenAcceptAsync:无返回值
CompletableFuture<String> C = B.thenApplyAsync((result) -> {
//这里需要B的结果做些操作
String c = result + "C";
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
A.add(c);
return c;
}, THREAD_POOL_EXECUTOR);
CompletableFuture<String> D = B.thenApplyAsync((result) -> {
//这里需要B的结果做些操作
String d = result + "D";
A.add(d);
return d;
}, THREAD_POOL_EXECUTOR);
try {
CompletableFuture.allOf(D, C).get();
System.out.println(A);
} catch (Exception e) {
e.printStackTrace();
}
}
}
参考:
CompletableFuture使用详解_sermonlizhi的博客-CSDN博客_completablefuture
Java8 CompletableFuture 用法全解_孙大圣666的博客-CSDN博客_completablefuture