CompletableFuture.join() vs Future.get(),开发中哪个更好

CompletableFuture和Future都是Java中的接口,用于异步编程和并发处理。

Future表示一种异步计算的结果,可以通过get()方法获取计算结果或等待计算的完成。但是,如果计算还未完成,get()方法会阻塞线程,这会影响并发性能。此外,Future只能描述单个异步计算过程,无法组合多个任务的结果。

而CompletableFuture是Future的增强版本,在保留Future的基本功能的同时,还提供了更加方便的方法以支持异步操作的组合和链式调用。CompletableFuture可以将多个异步操作组合成一个新的异步计算,并通过回调方式处理结果,无需阻塞线程。

类信息 

CompletableFuture

Future 

CompletableFuture.join() vs Future.get(),开发中哪个更好_第1张图片

比较 

代码展示1

public class FutureExample {

    static ThreadPoolExecutor threadPool = new ThreadPoolExecutor(16, 32, 5, TimeUnit.HOURS, new LinkedBlockingQueue<>());
    public static void processFutures(List> futureList) {
        for (CompletableFuture future : futureList) {
            // 使用join()方法等待每个Future对象的结果,不会阻塞当前线程
            try {
                String result = future.join();
//                System.out.println("Future result: " + result);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        long millis = System.currentTimeMillis();
        List> futureList = new ArrayList<>();
        for (int i = 0; i < 10000000; i++) {
            int finalI = i;
            futureList.add(CompletableFuture.supplyAsync(() -> ("Result " + finalI)));
        }
        processFutures(futureList);
        System.out.println("join-----------------------" + (System.currentTimeMillis() - millis));

        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(15, 50, 5, TimeUnit.HOURS, new LinkedBlockingQueue<>());

        long millis2 = System.currentTimeMillis();
        List futures = new ArrayList<>();
        for (int i = 0; i < 10000000; i++) {
            int finalI = i;
            futures.add(threadPool.submit(() -> ("Result " + finalI)));
        }

        for (Future future : futures) {
            Object o = future.get();
//            System.out.println(o.toString());
        }
        System.out.println("get-----------------------" + (System.currentTimeMillis() - millis2));
    }
}

结果1

 代码展示2

修改线程池的第一个参数为32

结果2

 

 代码展示3

修改线程池的第二个参数为64

结果3

结论

在性能方面,CompletableFuture.join()和Future.get()的速度差异不大。它们都是阻塞方法,会等待异步任务完成并返回结果。具体哪一个更快取决于具体的使用场景和实现方式。

然而,CompletableFuture.join()相对于Future.get()有一个优点,就是它可以更方便地进行异常处理。如果异步任务抛出了异常,CompletableFuture.join()会将异常封装为CompletionException并抛出,而Future.get()则需要在调用get()方法之前显式地调用getException()方法来获取异常信息。

另外,CompletableFuture.join()还可以与其他CompletableFuture实例进行组合操作,实现更为复杂的异步任务处理。而Future.get()则只能用于获取单个异步任务的结果。

综上所述,虽然CompletableFuture.join()和Future.get()在性能上没有明显差异,但是在功能和使用方式上,CompletableFuture.join()更为灵活和方便。

你可能感兴趣的:(并发,java,后端,java,jvm,juc,Future)