【异步编程】CompletableFuture使用示例

基本的异步调用

该函数演示了如何使用CompletableFuture进行基本的异步调用:

  • 创建CompletableFuture,通过supplyAsync方法异步执行任务,任务包括打印当前线程名称、模拟耗时操作(睡眠2秒)并返回结果。
  • 主线程继续执行,不会因异步任务阻塞,打印“Main thread continues…”。
  • 通过future.get()等待异步任务完成并获取结果,最后打印结果。
    public void test() throws ExecutionException, InterruptedException {
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            System.out.println("Executing task in thread: " + Thread.currentThread().getName());
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            return "Result of the computation";
        });

        // 这里主线程不会阻塞,可以继续执行其他任务
        System.out.println("Main thread continues...");

        // 等待结果完成并获取结果
        String result = future.get();
        System.out.println("Result: " + result);
    }

运行结果:

Main thread continues...
Executing task in thread: ForkJoinPool.commonPool-worker-1
Result: Result of the computation

配合自定义线程池使用

该方法使用 CompletableFuture 和自定义线程池异步执行任务,使主线程能够继续执行其他操作。主要步骤如下:

  • 创建固定大小的线程池。
  • 使用线程池创建 CompletableFuture 并异步执行任务,打印执行任务的线程名称,并模拟任务执行时间。
  • 主线程继续执行其他任务。
  • 等待任务完成并获取结果,打印结果。
  • 关闭线程池并等待所有任务完成,处理可能的中断情况。
    public void test2() throws ExecutionException, InterruptedException {
        // 创建一个固定大小的线程池
        ExecutorService executor = Executors.newFixedThreadPool(5);

        // 使用自定义线程池创建CompletableFuture
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            // 打印当前执行任务的线程名称
            System.out.println("Executing task in thread: " + Thread.currentThread().getName());
            try {
                // 模拟任务执行时间
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                // 重新设置中断状态,以便后续可以检测到中断
                Thread.currentThread().interrupt();
            }
            // 返回任务执行结果
            return "Result of the computation";
        }, executor);

        // 这里主线程不会阻塞,可以继续执行其他任务
        System.out.println("Main thread continues...");

        // 等待结果完成并获取结果
        try {
            String result = future.get();
            // 打印任务结果
            System.out.println("Result: " + result);
        } catch (InterruptedException | ExecutionException e) {
            // 处理异常
            e.printStackTrace();
        }

        // 关闭线程池,不再接受新任务
        executor.shutdown();
        // 等待线程池中所有任务完成
        try {
            if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {
                // 如果在指定时间内未完成,则强制关闭所有活动任务
                executor.shutdownNow();
            }
        } catch (InterruptedException e) {
            // 如果等待过程中被中断,则强制关闭所有活动任务
            executor.shutdownNow();
            // 重新设置中断状态
            Thread.currentThread().interrupt();
        }
    }

输出:

Main thread continues...
Executing task in thread: pool-1-thread-1
Result: Result of the computation

链式调用示例

该函数演示了CompletableFuture的链式调用:

  • 使用supplyAsync异步执行第一步,并打印当前线程名,返回结果"Step 1 result"。
  • 通过thenApply方法,依次执行第二步和第三步,每步接收上一步的结果,在新线程中执行并修改结果字符串,最终获取并打印最终结果。
    public void chainExample() throws ExecutionException, InterruptedException {
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            System.out.println("Step 1: " + Thread.currentThread().getName());
            return "Step 1 result";
        }).thenApply(result -> {
            System.out.println("Step 2: " + Thread.currentThread().getName());
            return result + " -> Step 2 result";
        }).thenApply(result -> {
            System.out.println("Step 3: " + Thread.currentThread().getName());
            return result + " -> Step 3 result";
        });

        String finalResult = future.get();
        System.out.println("Final Result: " + finalResult);
    }

输出:

Step 1: ForkJoinPool.commonPool-worker-1
Step 2: main
Step 3: main
Final Result: Step 1 result -> Step 2 result -> Step 3 result

异常处理示例

本方法演示了如何在CompletableFuture中处理异常。

    public void exceptionHandlingExample() {
        // 创建一个CompletableFuture,异步执行一个任务
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            // 打印当前执行任务的线程名称
            System.out.println("Executing task in thread: " + Thread.currentThread().getName());
            // 模拟异常发生,用于测试异常处理机制
            if (true) {
                throw new RuntimeException("Something went wrong!");
            }
            // 正常情况下返回任务结果
            return "Result of the computation";
        })
        // 设置异常处理器
        .exceptionally(ex -> {
            // 打印异常信息
            System.out.println("Exception occurred: " + ex.getMessage());
            // 返回默认结果
            return "Default result";
        });

        // 处理CompletableFuture的结果
        future.thenAccept(result -> System.out.println("Result: " + result));
    }

输出:

Executing task in thread: ForkJoinPool.commonPool-worker-1
Exception occurred: java.lang.RuntimeException: Something went wrong!
Result: Default result

组合多个异步任务示例

    public void combineExample() throws ExecutionException, InterruptedException {
        CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
            System.out.println("Task 1: " + Thread.currentThread().getName());
            return "Result 1";
        });

        CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
            System.out.println("Task 2: " + Thread.currentThread().getName());
            return "Result 2";
        });

        CompletableFuture<String> combinedFuture = future1.thenCombine(future2, (result1, result2) -> {
            return result1 + " + " + result2;
        });

        String finalResult = combinedFuture.get();
        System.out.println("Combined Result: " + finalResult);
    }

输出:

Task 1: ForkJoinPool.commonPool-worker-1
Task 2: ForkJoinPool.commonPool-worker-1
Combined Result: Result 1 + Result 2

任意一个完成示例

public void anyOfExample() throws ExecutionException, InterruptedException {
        CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            return "Result 1";
        });

        CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            return "Result 2";
        });

        CompletableFuture<Object> anyOfFuture = CompletableFuture.anyOf(future1, future2);

        Object result = anyOfFuture.get();
        System.out.println("First completed result: " + result);
    }

输出:

First completed result: Result 2

所有任务完成示例

    public void allOfExample() throws ExecutionException, InterruptedException {
        CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            return "Result 1";
        });

        CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            return "Result 2";
        });

        CompletableFuture<String> future3 = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            return "Result 3";
        });

        CompletableFuture<Void> allOfFuture = CompletableFuture.allOf(future1, future2, future3);

        allOfFuture.get();  // 等待所有任务完成

        System.out.println("All tasks completed.");
        System.out.println("Future 1 result: " + future1.get());
        System.out.println("Future 2 result: " + future2.get());
        System.out.println("Future 3 result: " + future3.get());
    }

输出:

All tasks completed.
Future 1 result: Result 1
Future 2 result: Result 2
Future 3 result: Result 3

等待多个任务完成后执行新任务示例

本方法演示了如何使用CompletableFuture来协调多个异步任务的执行顺序,它首先启动三个独立的异步任务A、B、C,然后等待它们都完成后,使用它们的结果来启动一个新的异步任务D,最后从任务D获取结果并打印出来

 public void dependentTasksExample() throws ExecutionException, InterruptedException {
        // 标记主线程的任务1
        System.out.println("main 1");

        // 启动异步任务A,模拟耗时操作并返回结果
        CompletableFuture<String> futureA = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            // 任务A执行结束
            System.out.println("A end");
            return "Result A";
        });

        // 启动异步任务B,模拟耗时操作并返回结果
        CompletableFuture<String> futureB = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            // 任务B执行结束
            System.out.println("B end");
            return "Result B";
        });

        // 启动异步任务C,模拟耗时操作并返回结果
        CompletableFuture<String> futureC = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            // 任务C执行结束
            System.out.println("C end");
            return "Result C";
        });

        // 等待所有已启动的CompletableFuture完成
        CompletableFuture<Void> allOfFutures = CompletableFuture.allOf(futureA, futureB, futureC);
        // 标记主线程的任务2
        System.out.println("main 2");

        // 创建新的CompletableFuture D,依赖于A、B、C的结果
        CompletableFuture<String> futureD = allOfFutures.thenCompose(v -> {
            return CompletableFuture.supplyAsync(() -> {
                // 任务D执行中
                System.out.println("Task D: " + Thread.currentThread().getName());
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
                // 任务D执行结束
                System.out.println("D end");
                // 返回任务D的结果,该结果是基于任务A、B、C的结果组合而成的
                return "D: " + futureA.join() + ", " + futureB.join() + ", " + futureC.join();
            });
        });
        // 标记主线程的任务3
        System.out.println("main 3");

        // 等待D完成并获取其结果
        String finalResult = futureD.get();
        // 打印最终结果
        System.out.println("Final Result from D: " + finalResult);
    }

输出:

main 1
main 2
main 3
C end
A end
B end
Task D: ForkJoinPool.commonPool-worker-3
D end
Final Result from D: D: Result A, Result B, Result C
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值