CompletableFuture中关于get和join的区别

发布时间 2023-08-15 07:52:12作者: LCAC

一、相同点

1、get和join都是用来等待获取CompletableFuture执行异步的返回

二、不同点

1、join()方法抛出的是uncheckException异常(即RuntimeException),不会强制开发者抛出

    /**
     * Returns the result value when complete, or throws an
     * (unchecked) exception if completed exceptionally. To better
     * conform with the use of common functional forms, if a
     * computation involved in the completion of this
     * CompletableFuture threw an exception, this method throws an
     * (unchecked) {@link CompletionException} with the underlying
     * exception as its cause.
     *
     * @return the result value
     * @throws CancellationException if the computation was cancelled
     * @throws CompletionException if this future completed
     * exceptionally or a completion computation threw an exception
     */
    @SuppressWarnings("unchecked")
    public T join() {
        Object r;
        if ((r = result) == null)
            r = waitingGet(false);
        return (T) reportJoin(r);
    }

如上是join的备注,及对应的代码。会抛出异常 CancellationException | CompletionException ,但是join是unchecked的

    private void testSupplyJoin() {
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            int i = 1 / 0;
            return "test";
        });

        String result = future.join();
    }

如上的调用所示:不需要是使用try-catch或者throws来对异常捕获或者抛出

 

2、get()方法抛出的是经过检查的异常,ExecutionException, InterruptedException 需要用户手动处理(抛出或者 try catch)

    /**
     * Waits if necessary for this future to complete, and then
     * returns its result.
     *
     * @return the result value
     * @throws CancellationException if this future was cancelled
     * @throws ExecutionException if this future completed exceptionally
     * @throws InterruptedException if the current thread was interrupted
     * while waiting
     */
    @SuppressWarnings("unchecked")
    public T get() throws InterruptedException, ExecutionException {
        Object r;
        if ((r = result) == null)
            r = waitingGet(true);
        return (T) reportGet(r);
    }

如上的get代码所示:get会抛出InterruptedException, ExecutionException,那么外部就需要做对应的捕获操作,如下所示使用try-catch的方式

    private void testSupplyGet() {
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            int i = 1 / 0;
            return "test";
        });

        try {
            String result = future.get();
        } catch (ExecutionException | InterruptedException e) {
            System.out.println(e);
        }
    }