注意:在分布式系统中如果使用feign做分布式调用,开启异步编排会导致feign丢失上下文
不建议的使用方式
public static void main(String[] args) throws ExecutionException, InterruptedException {
System.out.println("main...start");
Thread01 thread01 = new Thread01();
thread01.start();
Runable01 runable01 = new Runable01();
new Thread(runable01).start();
// ----Callable和futureTask可以获取返回值和处理异常
FutureTask<Integer> futureTask = new FutureTask<>(new Callable01());
new Thread(futureTask).start();
//阻塞等待\等待整个线程执行2完成,获取返回结果
Integer integer = futureTask.get();
//---------线程池提交任务------------
//在实际业务代码里面,以上启动线程方式都不用,将所有的异步任务都交给线程池
service.execute(new Runable01());
System.out.println("main...end: ");
}
定义线程池
public static ExecutorService service = Executors.newFixedThreadPool(10);
基本使用
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
System.out.println("当前线程:" + Thread.currentThread().getId());
int i = 10 / 2;
System.out.println("循行结果:" + i);
}, service);
获取异步线程的成功和失败结果
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程:" + Thread.currentThread().getId());
int i = 10 / 0;
System.out.println("循行结果:" + i);
return i;
}, service).whenComplete((res,excption)->{
//虽然能得到异常信息但是不能修改结果
System.out.println("异步任务成功完成了。。。结果是:"+res+
" 异常是: "+excption);
}).exceptionally(throwable -> {
//感知异常,返回默认值
return 10;
});
方法完成后的处理,无论成功还是失败
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程:" + Thread.currentThread().getId());
int i = 10 / 4;
System.out.println("循行结果:" + i);
return i;
}, service).handle((res, throwable) -> {
if(res != null){
return res*2;
}
return 0;
});
串行化线程
thenRunAsync、thenRunAsync 、thenApplyAsync
- thenRunAsync,不能湖区上一步的执行结果 无返回值
- thenRunAsync 能接受上一步结果,无返回值
- thenApplyAsync; 能接收上一步结果,有返回值
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程:" + Thread.currentThread().getId());
int i = 10 / 4;
System.out.println("循行结果:" + i);
return i;
}, service).thenApplyAsync((res) -> {
System.out.println("任务为启动了:" + res);
return "hello" + res;
}, service);
两个任务都完成
CompletableFuture<Object> future01 = CompletableFuture.supplyAsync(() -> {
System.out.println("任务1线程:" + Thread.currentThread().getId());
int i = 10 / 4;
System.out.println("任务1结束:");
return i;
}, service);
CompletableFuture<Object> future02 = CompletableFuture.supplyAsync(() -> {
System.out.println("任务2线程:" + Thread.currentThread().getId());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("任务2结束:");
return "hello";
}, service);
1)runAfterBothAsync(等待两个任务结束后执行)不能感知前两个的结果
future01.runAfterBothAsync(future02,()->{
System.out.println("任务3线程:" + Thread.currentThread().getId());
},service);
2) thenAcceptBothAsync (等待两个任务结束后执行)可以感知前两个的结果
future01.thenAcceptBothAsync(future02,(f1,f2)->{
System.out.println("之前的结果:f1: "+f1+" f2:"+f2);
System.out.println("任务3线程:" + Thread.currentThread().getId());
},service);
3) thenCombineAsync: 可以感知前面两个结果,也能自己在返回新的结果
CompletableFuture<String> future = future01.thenCombineAsync(future02, (f1, f2) -> {
return f1 + ": " + f2 + "hah";
}, service);
两个任务只要有一个任务完成就执行任务
CompletableFuture<Object> future01 = CompletableFuture.supplyAsync(() -> {
System.out.println("任务1线程:" + Thread.currentThread().getId());
int i = 10 / 4;
System.out.println("任务1结束:");
return i;
}, service);
CompletableFuture<Object> future02 = CompletableFuture.supplyAsync(() -> {
System.out.println("任务2线程:" + Thread.currentThread().getId());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("任务2结束:");
return "hello";
}, service);
1.runAfterEitherAsync 不感知结果,也没有返回值
future01.runAfterEitherAsync(future02,()->{
System.out.println("任务三开始了");
},service);
future01.acceptEitherAsync(future02,(res)->{
System.out.println("任务三开始 ---接收的的结果:"+res);
},service);
2.applyToEitherAsync 自己感知结果,自己有返回值
CompletableFuture<String> future = future01.applyToEitherAsync(future02, (res) -> {
System.out.println("任务三开始 ---接收的的结果:" + res);
return res.toString() + "--->哈哈";
}, service);
多个异步执行方式
CompletableFuture<String> futureImg = CompletableFuture.supplyAsync(() -> {
System.out.println("查询商品的图片信息");
return "hello.jpg";
}, service);
CompletableFuture<String> futureAttr = CompletableFuture.supplyAsync(() -> {
System.out.println("查询商品的属性");
return "黑色+256G";
}, service);
CompletableFuture<String> futureDesc = CompletableFuture.supplyAsync(() -> {
System.out.println("查询商品的介绍");
return "华为";
}, service);
1.allOf全部执行完才结束
all.get() //等待所有结果完成
CompletableFuture<Void> all = CompletableFuture.allOf(futureImg, futureAttr, futureDesc);
all.get();
2.anyOf只要有一个成功就结束
CompletableFuture<Object> anyOf = CompletableFuture.anyOf(futureImg, futureAttr, futureDesc);
anyOf.get(); //获取执行完的哪一个任务的结果
System.out.println("main...end: "+ anyOf.get());
dome实例
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
return "获取sku基本信息";
}, executor);
//在sku的基础上
CompletableFuture<Void> attr = future.thenAcceptAsync((res) -> {
System.out.println("获取spu的销售属性不需要返回值,得到的sku的返回值为:" + res);
System.out.println("获取spu的销售属性");
}, executor);
//在sku的基础上
CompletableFuture<Void> desv = future.thenAcceptAsync((res) -> {
System.out.println("sou介绍不需要返回值,得到的sku的返回值为:" + res);
System.out.println("获取spu的介绍");
}, executor);
//在sku的基础上
CompletableFuture<Void> base = future.thenAcceptAsync((res) -> {
System.out.println("获取spu的规格参数不需要返回值,得到的sku的返回值为:" + res);
System.out.println("获取spu的规格参数");
}, executor);
//可以直接执行
CompletableFuture<Void> imageFutrue = CompletableFuture.runAsync(() -> {
System.out.println("获取sku的图片信息");
}, executor);
//等待所有任务都完成,基本信息异步可省略
CompletableFuture.allOf(attr, desv, base, imageFutrue).get();
System.out.println("等待所有异步和执行完");