使用CompletableFuture替代Thread+Runnable
解决Thread+Runnable没有返回值、串行化和组合任务问题
1、CompletableFuture.runAsync 异步没有返回值
需要传入一个线程池
public static ExecutorService executor = Executors.newFixedThreadPool(10);
CompletableFuture.runAsync(()->{
System.out.println("当前线程:"+Thread.currentThread().getId());
int i = 10/2;
System.out.println("运行结果:"+ i );
},executor);
2、CompletableFuture.supplyAsync 异步有返回值
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程:" + Thread.currentThread().getId());
int i = 10 / 2;
System.out.println("运行结果:" + i);
return i;
}, executor).handle((res,thr)->{//结果处理,res 结果,thr 异常
if(res !=null){
return res*2;
}
if(thr!=null){
return 0;
}
return 0;
});
Integer i = future.get();// 阻塞
3、线程串行化
没有接收结果
/**
* 线程串行化
*/
CompletableFuture<Void> future = CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程:" + Thread.currentThread().getId());
int i = 10 / 2;
System.out.println("运行结果:" + i);
return i;
}, executor).thenRunAsync(() -> {
System.out.println("任务2执行成功");
}, executor);
有接收结果
CompletableFuture<Void> future = CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程:" + Thread.currentThread().getId());
int i = 10 / 2;
System.out.println("运行结果:" + i);
return i;
}, executor).thenAcceptAsync((res)->{
System.out.println("任务2启动了.."+res);
},executor);
接收结果,并修改返回结果
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程:" + Thread.currentThread().getId());
int i = 10 / 2;
System.out.println("运行结果:" + i);
return i;
}, executor).thenApplyAsync((res) -> {
System.out.println("任务2启动了...");
return "hello " + res;
}, executor);
String s = future.get(); // 阻塞
4、组合任务-都要完成
需等组合任务完成,第三个线程才开始
CompletableFuture<Integer> future01 = CompletableFuture.supplyAsync(() -> {
System.out.println("任务1启动了...");
return 5;
}, executor);
CompletableFuture<Integer> future02 = CompletableFuture.supplyAsync(() -> {
System.out.println("任务2启动了...");
return 5;
}, executor);
future01.runAfterBothAsync(future02,()->{
System.out.println("任务3开始...");
},executor);
组合任务都完成,感知结果
CompletableFuture<Integer> future01 = CompletableFuture.supplyAsync(() -> {
System.out.println("任务1启动了...");
return 5;
}, executor);
CompletableFuture<Integer> future02 = CompletableFuture.supplyAsync(() -> {
System.out.println("任务2启动了...");
return 5;
}, executor);
future01.thenAcceptBothAsync(future02,(f1,f2)->{
System.out.println("任务3开始...之前的结果:"+f1+"-> "+ f2);
},executor);
组合任务都完成,感知结果,并重新返回值
CompletableFuture<Integer> future01 = CompletableFuture.supplyAsync(() -> {
System.out.println("任务1启动了...");
return 5;
}, executor);
CompletableFuture<Integer> future02 = CompletableFuture.supplyAsync(() -> {
System.out.println("任务2启动了...");
return 5;
}, executor);
CompletableFuture<Integer> future = future01.thenCombineAsync(future02, (f1, f2) -> {
System.out.println("任务3开始...之前的结果:" + f1 + "-> " + f2);
return f1 + f2;
}, executor);
Integer i = future.get();
5、组合任务-一个完成
两个任务,只要有一个完成,我们就执行任务3。
没有感知结果,没有返回值
CompletableFuture<Integer> future01 = CompletableFuture.supplyAsync(() -> {
System.out.println("任务1启动了...");
return 5;
}, executor);
CompletableFuture<Integer> future02 = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(3000);
System.out.println("任务2启动了...");
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return 5;
}, executor);
future01.runAfterEitherAsync(future02,()->{
System.out.println("任务3启动了...");
},executor);
感知结果
CompletableFuture<Integer> future01 = CompletableFuture.supplyAsync(() -> {
System.out.println("任务1启动了...");
return 5;
}, executor);
CompletableFuture<Integer> future02 = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(3000);
System.out.println("任务2启动了...");
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return 5;
}, executor);
/**
* 需相同返回类型
*/
future01.acceptEitherAsync(future02,(res)->{
System.out.println("任务3启动了...");
},executor);
感知结果,并且有返回值
CompletableFuture<Integer> future01 = CompletableFuture.supplyAsync(() -> {
System.out.println("任务1启动了...");
return 5;
}, executor);
CompletableFuture<Integer> future02 = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(3000);
System.out.println("任务2启动了...");
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return 5;
}, executor);
/**
* 需相同返回类型
*/
CompletableFuture<Integer> future = future01.applyToEitherAsync(future02, (res) -> {
System.out.println("任务3启动了...");
return res + 1;
}, executor);
Integer i = future.get();
6、多任务组合(常用)
allOf:等待所有任务完成
anyOf:只要有一个任务完成
allOf,等待所有任务完成
CompletableFuture<String> futureImg = CompletableFuture.supplyAsync(() -> {
System.out.println("查询商品的图片信息");
return "hello.jpg";
}, executor);
CompletableFuture<String> futureAttr = CompletableFuture.supplyAsync(() -> {
System.out.println("查询商品的属性");
return "黑色+256G";
}, executor);
CompletableFuture<String> futureDesc = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("查询商品介绍");
return "华为";
}, executor);
CompletableFuture<Void> allOf = CompletableFuture.allOf(futureImg, futureAttr, futureDesc);
allOf.get(); // 阻塞等待所有线程完成
String s = futureImg.get();
String s1 = futureAttr.get();
String s2 = futureDesc.get();
anyOf,只要有一个任务完成
CompletableFuture<String> futureImg = CompletableFuture.supplyAsync(() -> {
System.out.println("查询商品的图片信息");
return "hello.jpg";
}, executor);
CompletableFuture<String> futureAttr = CompletableFuture.supplyAsync(() -> {
System.out.println("查询商品的属性");
return "黑色+256G";
}, executor);
CompletableFuture<String> futureDesc = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("查询商品介绍");
return "华为";
}, executor);
CompletableFuture<Object> anyOf = CompletableFuture.anyOf(futureImg, futureAttr, futureDesc);
anyOf.get(); // 阻塞等待所有线程完成