JAVA8 CompletableFuture异步编程教程

本文介绍了如何在Java中使用CompletableFuture进行简单异步操作,并指出默认线程池可能导致的问题。随后,作者展示了如何通过whenComplete方法优化,实现任务完成后的回调和错误处理。最后提供了实际代码示例,包括游戏场景的异步任务并发执行。

CompletableFuture

前言

本文章只是个人简单测试使用的,如果用到项目中 请按项目实际情况使用

简单使用

注意点:使用CompletableFuture默认的线程池则主线程结束整个方法执行就会结束,不会等待异步方法执行完成

String types[] = {"4362","8924","4363","8801"};
TimeInterval timer = DateUtil.timer();

List<SpdbInterLog> list00 = new ArrayList<>();
List<SpdbInterLog> list11 = new ArrayList<>();
CompletableFuture<List<SpdbInterLog>> listCompletableFuture = CompletableFuture.supplyAsync(() -> {
    Page page = new Page();
    page.setCurrent(1);
    page.setSize(10000);
    System.out.println(JSON.toJSONString(types));
    return spdbInterLogService.page(page,Wrappers.<SpdbInterLog>lambdaQuery().in(SpdbInterLog::getType, types)).getRecords();
});

CompletableFuture<List<SpdbInterLog>> listCompletableFuture1 = CompletableFuture.supplyAsync(() -> {
    Page page = new Page();
    page.setCurrent(1);
    page.setSize(10000);
    return spdbInterLogService.page(page).getRecords();
});
list00 = listCompletableFuture.get();
list11 = listCompletableFuture1.get();
//注:只有当点get方法的时候每次执行都有数据,否则没有点get()等待方法执行完成的会获得空数据
System.out.println("list00大小="+list00.size());
System.out.println("list11大小="+list11.size());
long interval = timer.interval();
if (list00.size()==list11.size()) {
    return R.ok(interval);
}
return R.failed(interval);

获取空数据例子

String types[] = {"4362","8924","4363","8801"};
TimeInterval timer = DateUtil.timer();

List<SpdbInterLog> list00 = new ArrayList<>();
List<SpdbInterLog> list11 = new ArrayList<>();
CompletableFuture<List<SpdbInterLog>> listCompletableFuture = CompletableFuture.supplyAsync(() -> {
    Page page = new Page();
    page.setCurrent(1);
    page.setSize(10000);
    System.out.println(JSON.toJSONString(types));
    return spdbInterLogService.page(page,Wrappers.<SpdbInterLog>lambdaQuery().in(SpdbInterLog::getType, types)).getRecords();
});

CompletableFuture<List<SpdbInterLog>> listCompletableFuture1 = CompletableFuture.supplyAsync(() -> {
    Page page = new Page();
    page.setCurrent(1);
    page.setSize(10000);
    return spdbInterLogService.page(page).getRecords();
});
list00 = listCompletableFuture.get();
//listCompletableFuture1没有点get方法所以执行的时候返回结果可能为空
System.out.println("list00大小="+list00.size());
System.out.println("list11大小="+list11.size());
long interval = timer.interval();
if (list00.size()==list11.size()) {
    return R.ok(interval);
}
return R.failed(interval);

优化

可以吧get方法换成whenComplete方法CompletableFuture:CompletableFuture的whenComplete方法表示,某个任务执行完成后,执行的回调方法,无返回值;并且whenComplete方法返回的CompletableFuture的result是上个任务的结果。

注意:whenComplete程序出错后不会正常执行,handle和whenComplete用法一致,但handle在程序出错后会继续执行,此方法比whenComplete多返回值,两个方法可以一起使用哦

System.out.println("游戏开始");
ExecutorService executor = Executors.newFixedThreadPool(5);
CompletableFuture.supplyAsync(()->{
    System.out.println("开始超级马里奥游戏-----");
    try {
        Thread.sleep(2000*2);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    return "怪已被全部击败";
},executor).whenComplete((result,e)->{
    System.out.println(result+"游戏结束");
});

CompletableFuture.supplyAsync(()->{
    System.out.println("开始狂野飙车游戏-----");
    try {
        Thread.sleep(2000*4);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    return "追赶第一";
},executor).whenComplete((result,e)->{
    System.out.println(result+"游戏结束");
});

CompletableFuture.supplyAsync(()->{
    System.out.println("开始飞机大战游戏-----");
    try {
        Thread.sleep(2000*1);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    return "飞机全部被打下";
},executor).whenComplete((result,e)->{
    System.out.println(result+"游戏结束");
});

System.out.println("111111111111111111");
executor.shutdown();
System.out.println("222222222222222222");

int i=0;
while (true){
    String format = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
    System.out.println(format);
    try {
        Thread.sleep(1000);
        i++;
        if (i>=10) {
            break;
        }
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

控制台打印输出:
    
游戏开始
开始超级马里奥游戏-----
开始狂野飙车游戏-----
开始飞机大战游戏-----
111111111111111111
222222222222222222
2021-12-03 08:55:06
2021-12-03 08:55:07
飞机全部被打下游戏结束
2021-12-03 08:55:08
2021-12-03 08:55:09
怪已被全部击败游戏结束
2021-12-03 08:55:10
2021-12-03 08:55:11
2021-12-03 08:55:12
2021-12-03 08:55:13
追赶第一游戏结束
2021-12-03 08:55:14
2021-12-03 08:55:15
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一个小浪吴啊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值