JAVA8 CompletableFuture异步编程教程

简介: JAVA8 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
相关文章
|
8天前
|
XML JavaScript Java
Java 中文官方教程 2022 版(四十)(4)
Java 中文官方教程 2022 版(四十)
38 0
|
4天前
|
Java 编译器 API
Java基础教程(17)-Java8中的lambda表达式和Stream、Optional
【4月更文挑战第17天】Lambda表达式是Java 8引入的函数式编程特性,允许函数作为参数或返回值。它有简洁的语法:`(parameters) -> expression 或 (parameters) ->{ statements; }`。FunctionalInterface注解用于标记单方法接口,可以用Lambda替换。
|
5天前
|
消息中间件 缓存 NoSQL
Java多线程实战-CompletableFuture异步编程优化查询接口响应速度
Java多线程实战-CompletableFuture异步编程优化查询接口响应速度
|
5天前
|
数据采集 前端开发 测试技术
《手把手教你》系列技巧篇(三十一)-java+ selenium自动化测试- Actions的相关操作-番外篇(详解教程)
【4月更文挑战第23天】本文介绍了网页中的滑动验证码的实现原理和自动化测试方法。作者首先提到了网站的反爬虫机制,并表示在本地创建一个没有该机制的网页,然后使用谷歌浏览器进行验证。接着,文章详细讲解了如何使用WebElement的click()方法以及Action类提供的API来模拟鼠标的各种操作,如右击、双击、悬停和拖动。
8 2
|
6天前
|
Web App开发 数据采集 Java
《手把手教你》系列技巧篇(三十)-java+ selenium自动化测试- Actions的相关操作下篇(详解教程)
【4月更文挑战第22天】本文介绍了在测试过程中可能会用到的两个功能:Actions类中的拖拽操作和划取字段操作。拖拽操作包括基本讲解、项目实战、代码设计和参考代码,涉及到鼠标按住元素并将其拖动到另一个元素上或指定位置。划取字段操作则介绍了如何在一段文字中随机选取一部分,包括项目实战、代码设计和参考代码。此外,文章还提到了滑动验证的实现,并提供了相关的代码示例。
33 2
|
6天前
|
安全 Java
Java基础教程(15)-多线程基础
【4月更文挑战第15天】Java内置多线程支持,通过Thread类或Runnable接口实现。线程状态包括New、Runnable、Blocked、Waiting、Timed Waiting和Terminated。启动线程调用start(),中断线程用interrupt(),同步用synchronized关键字。线程安全包如java.util.concurrent提供并发集合和原子操作。线程池如ExecutorService简化任务管理,Callable接口允许返回值,Future配合获取异步结果。Java 8引入CompletableFuture支持回调。
|
8天前
|
XML 算法 搜索推荐
Java 中文官方教程 2022 版(四十九)(4)
Java 中文官方教程 2022 版(四十九)
34 0
|
8天前
|
XML 自然语言处理 安全
Java 中文官方教程 2022 版(四十九)(3)
Java 中文官方教程 2022 版(四十九)
26 0
|
8天前
|
XML Java 编译器
Java 中文官方教程 2022 版(四十九)(2)
Java 中文官方教程 2022 版(四十九)
29 0
|
8天前
|
XML 网络协议 Java
Java 中文官方教程 2022 版(四十八)(3)
Java 中文官方教程 2022 版(四十八)
8 0