初识CompletableFuture和线程池


前言

CompletableFuture是JDK1.8的特性,用到了异步IO多路复用技术,配合线程池使用提高服务QPS。


一、上代码

TestCompletableFuture.java

package thread;

import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Stream;

/**
 * Create by zjg on 2023/4/28
 */
public class TestCompletableFuture {
    private static ExecutorService executorService = Executors.newFixedThreadPool(5);
    public static void main(String args[]) throws ExecutionException, InterruptedException {
        try {
            supplyAsync();
            System.out.println("-----方法分隔符-----");
            runAsync();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            shutdown();
        }
    }
    public static void supplyAsync() throws ExecutionException, InterruptedException {
        CompletableFuture<String> cfs1 = CompletableFuture.supplyAsync(() -> {//Supplier,有返回值
            System.out.println("cfs1:"+Thread.currentThread().getName() + "-start");//默认线程池ForkJoinPool
            try {
                Thread.sleep(2000);//演示anyOf
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //throw new RuntimeException("ex");
            return "Hello CompletableFuture1!";
        });
        CompletableFuture<String> cfs2 = CompletableFuture.supplyAsync(()->{
            System.out.println("cfs2:"+Thread.currentThread().getName()+"-start");//自定义线程池(可控)
            return "Hello CompletableFuture2!";
        },executorService);
        handle(cfs1,cfs2);
    }
    public static void runAsync() throws ExecutionException, InterruptedException {
        CompletableFuture<Void> cfs1 = CompletableFuture.runAsync(()->{//Runnable,无返回值
            System.out.println("cfs1:"+Thread.currentThread().getName() + "-start");//默认线程池ForkJoinPool
            try {
                Thread.sleep(2000);//演示anyOf
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //throw new RuntimeException("ex");
        });
        CompletableFuture<Void> cfs2 = CompletableFuture.runAsync(()->{
            System.out.println("cfs2:"+Thread.currentThread().getName()+"-start");//自定义线程池(可控)
        },executorService);
        handle(cfs1,cfs2);
    }
    public static void handle(CompletableFuture<?>... cfs) throws ExecutionException, InterruptedException {
        System.out.println();
        String s = CompletableFuture.anyOf(cfs).handle((res, ex) -> {
            if(Optional.ofNullable(res).isPresent()){
                System.out.println(res);
            }
            if(Optional.ofNullable(ex).isPresent()){
                System.out.println(ex);
            }
            isDoneOut(cfs);
            return "1和2其中一个处理完成";
        }).get();
        System.out.println(s);
        System.out.println();

        String cfs1Res = cfs[0].handleAsync((res, ex) -> {
            if(ex!=null){
                System.out.println("cfs1:发生异常:" + ex.getMessage());
                return "500";
            }
            System.out.println("cfs1:处理结果:"+res);
            return "200";
        }).get();
        System.out.println("cfs1:状态码:"+cfs1Res);
        System.out.println();

        String s1 = CompletableFuture.allOf(cfs).handle((res, ex) -> {
            if (Optional.ofNullable(res).isPresent()) {
                System.out.println(res);
            }
            if (Optional.ofNullable(ex).isPresent()) {
                System.out.println(ex);
            }
            getOut(cfs);
            isDoneOut(cfs);
            return "1和2全部处理完成";
        }).get();
        System.out.println(s1);
        System.out.println("success");
    }
    public static void isDoneOut(CompletableFuture<?>... cfs){
        Stream.iterate(0, i -> i + 1).limit(cfs.length).forEach(index -> {
            System.out.println("cfs" + (index+1)+":"+ cfs[index].isDone());
        });
    }
    public static void getOut(CompletableFuture<?>... cfs){
        Stream.iterate(0, i -> i + 1).limit(cfs.length).forEach(index -> {
            try {
                System.out.println("cfs" + (index+1)+":"+ cfs[index].get());
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        });
    }
    public static void shutdown(){
        executorService.shutdown();
    }
}


二、输出

cfs1:ForkJoinPool.commonPool-worker-1-start

cfs2:pool-1-thread-1-start
Hello CompletableFuture2!
cfs1:false
cfs2:true
12其中一个处理完成

cfs1:处理结果:Hello CompletableFuture1!
cfs1:状态码:200

cfs1:Hello CompletableFuture1!
cfs2:Hello CompletableFuture2!
cfs1:true
cfs2:true
12全部处理完成
success
-----方法分隔符-----
cfs1:ForkJoinPool.commonPool-worker-2-start

cfs2:pool-1-thread-2-start
cfs1:false
cfs2:true
12其中一个处理完成

cfs1:处理结果:null
cfs1:状态码:200

cfs1:null
cfs2:null
cfs1:true
cfs2:true
12全部处理完成
success

总结

supplyAsyncrunAsync两个方法最大的区别是,前者回调返回值是一个泛型,后者泛型为Void会get到null值,所以具体使用哪个方法看情况而定。
回到顶部

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值