CompletableFuture使用一些示例

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]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值