tips:本篇文章不从理论上讲解CompletableFuture的各API,网上已经很多了。这里只会做各种使用示例的演示。
User类,下面例子中有用到。
@Data
public class User {
private Integer id;
private String name;
private String address;
}
1. runAsync使用示例
使用CompletableFuture异步处理list里的每个user的address,并获取处理后的结果集
public static void main(String[] args) throws Exception{
ArrayList<User> list = new ArrayList<>();
list.add(new User(1,"张三","南山区"));
list.add(new User(2,"李四","宝安区"));
list.add(new User(3,"王五","福田区"));
list.add(new User(4,"赵六","罗湖区"));
//1.runAsync-无返回值
CompletableFuture<Void> completableFuture = CompletableFuture.runAsync(() -> {
System.out.println("线程名称=" + Thread.currentThread().getName());
System.out.println("=======runAsync开始执行========");
try {
Thread.sleep(5 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
list.forEach(s -> {
s.setAddress("SZ-" + s.getAddress());
});
System.out.println("=======runAsync执行end========");
});
System.out.println("主线程名称="+Thread.currentThread().getName());
completableFuture.join();
System.out.println("list="+list);
}
结果:
主线程名称=main
线程名称=ForkJoinPool.commonPool-worker-1
=======runAsync开始执行========
=======runAsync执行end========
list=[User{id=1, name='张三', address='SZ-南山区'}, User{id=2, name='李四', address='SZ-宝安区'}, User{id=3, name='王五', address='SZ-福田区'}, User{id=4, name='赵六', address='SZ-罗湖区'}]
2. supplyAsync使用示例1
通过allOf()工具方法,将List<CompletableFuture>转为CompletableFuture<List>
public static void main(String[] args) throws Exception{
ArrayList<User> list = new ArrayList<>();
list.add(new User(1,"张三","南山区"));
list.add(new User(2,"李四","宝安区"));
list.add(new User(3,"王五","福田区"));
list.add(new User(4,"赵六","罗湖区"));
List<CompletableFuture<User>> futures = list.stream().map(s -> CompletableFuture.supplyAsync(() -> {
s.setAddress("SZ-" + s.getAddress());
return s;
})).collect(Collectors.toList());
//这里的allOf是一个工具方法
CompletableFuture<List<User>> completableFuture1 = allOf(futures);
List<User> users = completableFuture1.join();
System.out.println("users="+users);
}
public static <T> CompletableFuture<List<T>> allOf(List<CompletableFuture<T>> futures) {
CompletableFuture<Void> allDoneFuture =
CompletableFuture.allOf(futures.toArray(new CompletableFuture[futures.size()]));
return allDoneFuture.thenApply(v ->
futures.stream().
map(future -> future.join()).
collect(Collectors.<T>toList())
);
}
结果:
users=[User{id=1, name='张三', address='SZ-南山区'}, User{id=2, name='李四', address='SZ-宝安区'}, User{id=3, name='王五', address='SZ-福田区'}, User{id=4, name='赵六', address='SZ-罗湖区'}]
3. supplyAsync使用示例2
处理List<CompletableFuture>,从每一个CompletableFuture获取到结果,并收集起来
public static void main(String[] args) throws Exception{
ArrayList<User> list = new ArrayList<>();
list.add(new User(1,"张三","南山区"));
list.add(new User(2,"李四","宝安区"));
list.add(new User(3,"王五","福田区"));
list.add(new User(4,"赵六","罗湖区"));
List<CompletableFuture<User>> collect = list.stream().map(s -> CompletableFuture.supplyAsync(() -> {
if (s.getId().equals(1)) {
try {
Thread.sleep(1000 * 5);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
s.setAddress("SZ-" + s.getAddress());
return s;
})).collect(Collectors.toList());
CompletableFuture.allOf(collect.toArray(new CompletableFuture[collect.size()]));
List<User> collect1 = collect.stream().map(s -> s.join()).collect(Collectors.toList());
System.out.println(collect1);
}
结果:
[User{id=1, name='张三', address='SZ-南山区'}, User{id=2, name='李四', address='SZ-宝安区'}, User{id=3, name='王五', address='SZ-福田区'}, User{id=4, name='赵六', address='SZ-罗湖区'}]
4. supplyAsync结合thenApply、whenComplete、exceptionally综合使用
此案例中,最后处理的结果通过一个外部定义的resultList 接收。最后通过CompletableFuture.allOf(completableFutures1).join()
进行阻塞获取结果,保证所有的都异步任务都执行完成。
public static void main(String[] args) throws ExecutionException, InterruptedException {
List<String> list = Arrays.asList("a", "b", "c", "d");
ArrayList<String> resultList = new ArrayList<>();
CompletableFuture[] completableFutures1 = list.stream().map(s -> CompletableFuture.supplyAsync(() -> {
System.out.println("supplyAsync执行开始。。。。。");
if (s.equals("c") || s.equals("b")) {
try {
Thread.sleep(1000 * 10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("supplyAsync执行完成。。。。。");
return s + "-one";
})
.thenApply(s2 -> s2.toUpperCase())
.whenComplete((str, thr) -> {
if (thr == null) {
System.out.println("whenComplete执行start...,str=" + str);
str = str + "-two";
System.out.println("whenComplete执行end...,str=" + str);
resultList.add(str);
} else {
System.err.println("发生异常,s=" + s);
}
}).exceptionally(s3 -> {
System.out.println("执行失败。。。。。。。。。。");
return null;
})
).toArray(CompletableFuture[]::new);
CompletableFuture.allOf(completableFutures1).join();
System.out.println("最后结果:"+resultList);
}
结果:
supplyAsync执行开始。。。。。
supplyAsync执行完成。。。。。
whenComplete执行start...,str=A-ONE
whenComplete执行end...,str=A-ONE-two
supplyAsync执行开始。。。。。
supplyAsync执行开始。。。。。
supplyAsync执行开始。。。。。
supplyAsync执行完成。。。。。
whenComplete执行start...,str=D-ONE
whenComplete执行end...,str=D-ONE-two
supplyAsync执行完成。。。。。
supplyAsync执行完成。。。。。
whenComplete执行start...,str=C-ONE
whenComplete执行end...,str=C-ONE-two
whenComplete执行start...,str=B-ONE
whenComplete执行end...,str=B-ONE-two
最后结果:[A-ONE-two, D-ONE-two, C-ONE-two, B-ONE-two]