使用CompletableFuture优化Java中的阻塞任务

2024-07-01 17:03:56 浏览数 (2)

在Java中,CompletableFuture 是一个用于异步编程的类,它代表了某个计算的结果,这个计算可能还没有完成。CompletableFuture 提供了多种方法来处理异步任务,包括 supplyAsyncrunAsync。其中,supplyAsync 用于产生返回值的任务,而 runAsync 用于没有返回值的任务。

使用 supplyAsync 处理有返回值的任务

supplyAsync 方法接受一个 Supplier 类型的参数,这个 Supplier 应该返回一个结果。supplyAsync 方法会异步地执行这个 Supplier,并返回一个 CompletableFuture,这个 CompletableFuture 会在计算完成时包含 Supplier 的结果。

下面是一个使用 supplyAsync 的示例:

代码语言:java复制
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

public class CompletableFutureExample {

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        // 创建一个有返回值的异步任务
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            // 模拟一个耗时的计算
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                throw new RuntimeException(e);
            }
            return "Hello, CompletableFuture!";
        });

        // 等待任务完成并获取结果
        String result = future.get();
        System.out.println(result); // 输出: Hello, CompletableFuture!
    }
}

使用 runAsync 处理无返回值的任务

runAsync 方法接受一个 Runnable 类型的参数,这个 Runnable 没有返回值。runAsync 方法会异步地执行这个 Runnable,并返回一个 CompletableFuture<Void>

下面是一个使用 runAsync 的示例:

代码语言:java复制
import java.util.concurrent.CompletableFuture;

public class CompletableFutureExample {

    public static void main(String[] args) {
        // 创建一个无返回值的异步任务
        CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
            // 模拟一个耗时的操作
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                throw new RuntimeException(e);
            }
            System.out.println("Task completed!"); // 直接在任务内部输出结果
        });

        // 由于任务是异步的,我们可以在这里添加其他逻辑
        // ...

        // 注意:对于Void类型的CompletableFuture,我们通常不需要调用get()来获取结果
        // 因为没有结果可以获取。但是,如果你想要等待任务完成,可以调用future.join()
        future.join(); // 等待任务完成,但不会返回结果
    }
}

等待所有请求完成

如果你有一组 CompletableFuture,并且你想要等待它们全部完成,你可以使用 CompletableFuture.allOf 方法。这个方法接受一个 CompletableFuture 数组,并返回一个表示所有 CompletableFuture 都已经完成的新的 CompletableFuture

下面是一个示例:

代码语言:java复制
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;

public class CompletableFutureExample {

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        List<CompletableFuture<Void>> futures = new ArrayList<>();

        // 创建多个异步任务并添加到列表中
        for (int i = 0; i < 5; i  ) {
            CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
                // 模拟一个耗时的操作
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    throw new RuntimeException(e);
                }
                System.out.println("Task "   Thread.currentThread().getId()   " completed!");
            });
            futures.add(future);
        }

        // 等待所有任务完成
        CompletableFuture<?> allFutures = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));
        allFutures.get(); // 阻塞直到所有任务完成

        System.out.println("All tasks completed!");
    }
}

0 人点赞