java CompletableFuture 配合线程池异步处理多个任务测试Demo

235 阅读2分钟

任务目标:4个人配合做一道水煮鱼

目标任务拆分

1. 市场距离较远,预计需要5秒,设置线程名称为:买鱼郎
    1.1 步行去市场 2秒
    1.2:挑鱼 1秒 
    1.3:步行回家 2秒 
2. 烧水,预计需要1秒,设置线程名称为:烧水哥
3. 买调料,预计3秒,设置线程名称为:调料姐
4. 做鱼,等待1,2,3步骤完成后,开始做鱼,预计4秒完成。设置线程名称为:大厨

结果预览:

image.png

代码流程:

// 买鱼郎线程
private static CompletableFuture<Long> completableFutureSupplyAsyncDemoSync_myl() throws ExecutionException, InterruptedException {
    return CompletableFuture.supplyAsync(() -> {
        Thread.currentThread().setName("买鱼郎");
        long begin = System.currentTimeMillis();
        log.info(Thread.currentThread().getName()+" 在:" +CompletableFutureTest.getNowDateStr()  + ",开始出发..目标鱼市,预计需要2秒");
    try {
        //处理任务区
        TimeUnit.SECONDS.sleep(2);
    } catch (InterruptedException e) {
        throw new RuntimeException(e);
    }
    log.info(Thread.currentThread().getName()+" 在:"+CompletableFutureTest.getNowDateStr()+"到达鱼市场");
        long end = System.currentTimeMillis();
        return end - begin;
}, threadPoolTaskExecutor).thenApply(f1->{
        long begin = System.currentTimeMillis();
        log.info(Thread.currentThread().getName()+" 在:" +CompletableFutureTest.getNowDateStr()  + ",开始挑鱼,预计需要1秒");
    try {
         //处理任务区
        TimeUnit.SECONDS.sleep(1);
    } catch (InterruptedException e) {
        throw new RuntimeException(e);
    }
        log.info(Thread.currentThread().getName()+" 在:" +CompletableFutureTest.getNowDateStr()  + ",挑鱼结束,准备回家");
        long end = System.currentTimeMillis();
        return ( end - begin) + f1;
}).thenApply(y2 -> {
        long begin = System.currentTimeMillis();
        log.info(Thread.currentThread().getName()+" 在:" +CompletableFutureTest.getNowDateStr()  + ",完成买鱼,准备回家,预计到家需要2秒");
    try {
         //处理任务区
        TimeUnit.SECONDS.sleep(2);
    } catch (InterruptedException e) {
        throw new RuntimeException(e);
    }
        log.info(Thread.currentThread().getName()+" 在:" +CompletableFutureTest.getNowDateStr()  + ",完成买鱼,已经到家,购买结束");
        long end = System.currentTimeMillis();
        long resultLong = ( end - begin) + y2;
        return resultLong;
}).whenComplete((v,e) -> {
        //接收异常信息,如果没有异常,返回值就是上一级的返回值
        // 如果出现异常可以在 exceptionally 进行保证出现异常时候给返回一个默认值
        if(ObjectUtil.isNotEmpty(v)){
        log.info("买鱼郎总计花费时间 "+v+" 毫秒完成任务");
    }else{
        e.printStackTrace();
    }
}).exceptionally(e->{
        e.printStackTrace();
        return null;
});

}
//烧水哥线程
private static CompletableFuture<Long> completableFutureSupplyAsyncDemoSync_ssg() throws ExecutionException, InterruptedException {
    return CompletableFuture.supplyAsync(() -> {
            long begin = System.currentTimeMillis();
            Thread.currentThread().setName("烧水哥");
            log.info(Thread.currentThread().getName()+" 在:" +CompletableFutureTest.getNowDateStr()  + ",开始准备烧水,预计需要1秒");
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            log.info(Thread.currentThread().getName()+" 在:"+CompletableFutureTest.getNowDateStr()+",烧水完成");
            long end = System.currentTimeMillis();
            long resultLong = end - begin;
            log.info("烧水哥总计花费:"+resultLong+" 毫秒完成烧水购买任务");
            return resultLong;
        }, threadPoolTaskExecutor);
}
//调料姐线程
private static CompletableFuture<Long> completableFutureSupplyAsyncDemoSync_tlj() throws ExecutionException, InterruptedException {
return CompletableFuture.supplyAsync(() -> {
            long begin = System.currentTimeMillis();
            Thread.currentThread().setName("调料姐");
            log.info(Thread.currentThread().getName()+" 在:" +CompletableFutureTest.getNowDateStr()  + ",开始准备购买调料,预计需要1秒");
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            log.info(Thread.currentThread().getName()+" 在:"+CompletableFutureTest.getNowDateStr()+",购买调料完成");
            long end = System.currentTimeMillis();
            long resultLong = end - begin;
            log.info("调料姐线程总计花费:"+resultLong+" 毫秒,完成调料购买任务");
            return resultLong;
        }, threadPoolTaskExecutor);
}
//厨师线程
private static CompletableFuture completableFutureSupplyAsyncDemoSync_dcs(CompletableFuture<Long> myl,
                                                                          CompletableFuture<Long> ssg,
                                                                          CompletableFuture<Long> tlj){
         return CompletableFuture.allOf(myl, ssg, tlj).thenApply(f -> {
            long begin = System.currentTimeMillis();
            Thread.currentThread().setName("厨师");
            log.info(Thread.currentThread().getName()+" 在:" +CompletableFutureTest.getNowDateStr()  + ",做鱼,预计需要4秒");
            try {
                TimeUnit.SECONDS.sleep(4);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            log.info(Thread.currentThread().getName()+" 在:"+CompletableFutureTest.getNowDateStr()+",做鱼完成");
            long end = System.currentTimeMillis();
            long resultLong = end - begin;
            log.info("厨师总计花费:"+resultLong+" 毫秒,完成做鱼任务");
            return resultLong;
        });                                                                                                                    
                                                                          }
//工具方法,获取当前时间
private static String getNowDateStr(){
    LocalDateTime nowEnd = LocalDateTime.now();
    return nowEnd.format(fmDateMax);
}
private static final Logger log = LoggerFactory.getLogger(CompletableFutureTest.class);
 // 线程池
 final static  ThreadPoolExecutor threadPoolTaskExecutor = new ThreadPoolExecutor(5, 20, 1L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(50), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
// 时间格式转换
final static DateTimeFormatter fmDateMax = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

// main方法调用
 public static void main(String[] args) throws ExecutionException, InterruptedException {
     // 买鱼
     CompletableFuture<Long> myl = CompletableFutureTest.completableFutureSupplyAsyncDemoSync_myl();
     // 烧水
     CompletableFuture<Long> ssg = CompletableFutureTest.completableFutureSupplyAsyncDemoSync_ssg();
     // 买调料
     CompletableFuture<Long> tlj = CompletableFutureTest.completableFutureSupplyAsyncDemoSync_tlj();
     CompletableFutureTest.completableFutureSupplyAsyncDemoSync_dcs(myl, ssg, tlj);
     threadPoolTaskExecutor.shutdown();
 }