CompletableFuture与多线程结合使用

14 篇文章 1 订阅
4 篇文章 0 订阅
本文介绍了Java8中的CompletableFuture类,它是Future的增强版,提供更灵活的异步编程方式。文章详细讲解了如何通过supplyAsync、runAsync和completedFuture创建CompletableFuture,以及如何使用get、thenApply、thenAccept、thenCompose、thenCombine和exceptionally等方法处理异步计算结果。同时,文中还展示了CompletableFuture与多线程结合使用的示例,以提高并发性能。
摘要由CSDN通过智能技术生成

前言

在Java 8中,引入了CompletableFuture类,它是Future的增强版,提供了更加灵活的异步编程方式,能够更好地利用多线程的优势。本文将详细讲解CompletableFuture的使用方法,并结合多线程实现异步编程。

CompletableFuture的概念

CompletableFuture是Java 8中新增的一个类,它实现了Future和CompletionStage接口,提供了一种更加灵活的异步编程方式。CompletableFuture可以看作是一个包含了计算结果的容器,可以在计算完成后获取结果,也可以在计算完成前执行一些操作。

与Future相比,CompletableFuture提供了更多的方法来处理异步计算的结果。它支持链式调用、组合多个CompletableFuture、异常处理等操作。

CompletableFuture的创建

CompletableFuture可以通过以下方式创建:

1. CompletableFuture.supplyAsync()

CompletableFuture.supplyAsync()方法可以创建一个异步计算任务,返回一个CompletableFuture对象。它接收一个Supplier类型的参数,用于执行异步计算。

示例代码:

CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
    // 异步计算任务
    return 1 + 2;
});

又如: 

import java.util.concurrent.*;

public class AsyncService {
    private final ExecutorService executorService;

    public AsyncService(int poolSize) {
        this.executorService = Executors.newFixedThreadPool(poolSize);
    }

    // 异步方法1
    public CompletableFuture<String> asyncMethod1() {
        return CompletableFuture.supplyAsync(() -> {
            // 执行一些长时间运行的任务...
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "Result of Method1";
        }, executorService);
    }

    // 异步方法2
    public CompletableFuture<String> asyncMethod2() {
        return CompletableFuture.supplyAsync(() -> {
            // 执行一些长时间运行的任务...
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "Result of Method2";
        }, executorService);
    }

    // 关闭线程池
    public void shutdown() {
        executorService.shutdown();
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        AsyncService asyncService = new AsyncService(10);
        CompletableFuture<String> future1 = asyncService.asyncMethod1();
        CompletableFuture<String> future2 = asyncService.asyncMethod2();
        System.out.println(future1.get());
        System.out.println(future2.get());
        asyncService.shutdown();
    }
}

2. CompletableFuture.runAsync()

CompletableFuture.runAsync()方法也可以创建一个异步计算任务,返回一个CompletableFuture对象。它接收一个Runnable类型的参数,用于执行异步计算。

示例代码:

CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
    // 异步计算任务
    System.out.println("异步计算任务执行完成");
});

CompletableFuture.runAsync()方法用于执行没有返回值的异步任务,又如:

import java.util.concurrent.*;

public class AsyncService {
    private final ExecutorService executorService;

    public AsyncService(int poolSize) {
        this.executorService = Executors.newFixedThreadPool(poolSize);
    }

    // 异步方法1
    public CompletableFuture<Void> asyncMethod1() {
        return CompletableFuture.runAsync(() -> {
            // 执行一些长时间运行的任务...
            try {
                System.out.println("Starting Method1...");
                Thread.sleep(2000);
                System.out.println("Finished Method1");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, executorService);
    }

    // 异步方法2
    public CompletableFuture<Void> asyncMethod2() {
        return CompletableFuture.runAsync(() -> {
            // 执行一些长时间运行的任务...
            try {
                System.out.println("Starting Method2...");
                Thread.sleep(2000);
                System.out.println("Finished Method2");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, executorService);
    }

    // 关闭线程池
    public void shutdown() {
        executorService.shutdown();
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        AsyncService asyncService = new AsyncService(10);
        CompletableFuture<Void> future1 = asyncService.asyncMethod1();
        CompletableFuture<Void> future2 = asyncService.asyncMethod2();
        CompletableFuture.allOf(future1, future2).join(); // 等待所有异步任务完成
        asyncService.shutdown();
    }
}

3. CompletableFuture.completedFuture()

CompletableFuture.completedFuture()方法可以创建一个已经完成的CompletableFuture对象,返回一个CompletableFuture对象。它接收一个静态值作为参数,表示已经完成的计算结果。

示例代码:

CompletableFuture<String> future = CompletableFuture.completedFuture("已经完成的计算结果");

CompletableFuture的使用

1. 获取计算结果

CompletableFuture的get()方法可以用于获取计算结果,如果计算尚未完成,则会阻塞当前线程直到计算完成。

示例代码:

CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
    // 异步计算任务
    return 1 + 2;
});
int result = future.get();
System.out.println(result);

2. 异步回调

CompletableFuture的thenApply()方法可以用于异步回调,它接收一个Function类型的参数,用于对计算结果进行转换。thenApply()方法返回一个新的CompletableFuture对象,它的计算结果为转换后的结果。

示例代码:

CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
    // 异步计算任务
    return 1 + 2;
});
CompletableFuture<String> future2 = future.thenApply(result -> "计算结果为:" + result);
String result2 = future2.get();
System.out.println(result2);

3. 异步消费

CompletableFuture的thenAccept()方法可以用于异步消费,它接收一个Consumer类型的参数,用于对计算结果进行消费。thenAccept()方法返回一个新的CompletableFuture对象,它的计算结果为原始结果。

示例代码:

CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
    // 异步计算任务
    return 1 + 2;
});
CompletableFuture<Void> future2 = future.thenAccept(result -> {
    System.out.println("计算结果为:" + result);
});
future2.get();

4. 异步组合

CompletableFuture的thenCompose()方法可以用于异步组合,它接收一个Function类型的参数,用于对计算结果进行组合。thenCompose()方法返回一个新的CompletableFuture对象,它的计算结果为组合后的结果。

示例代码:

CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
    // 异步计算任务
    return 1 + 2;
});
CompletableFuture<Integer> future2 = future.thenCompose(result -> CompletableFuture.supplyAsync(() -> {
    // 异步计算任务
    return result * 2;
}));
int result2 = future2.get();
System.out.println(result2);

5. 异步组合多个CompletableFuture

CompletableFuture的thenCombine()方法可以用于异步组合多个CompletableFuture,它接收一个BiFunction类型的参数,用于对多个计算结果进行组合。thenCombine()方法返回一个新的CompletableFuture对象,它的计算结果为组合后的结果。

示例代码:

CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> {
    // 异步计算任务
    return 1 + 2;
});
CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> {
    // 异步计算任务
    return 3 + 4;
});
CompletableFuture<Integer> future3 = future1.thenCombine(future2, (result1, result2) -> {
    // 异步计算任务
    return result1 + result2;
});
int result3 = future3.get();
System.out.println(result3);

6. 异常处理

CompletableFuture的exceptionally()方法可以用于异常处理,它接收一个Function类型的参数,用于处理异常情况。exceptionally()方法返回一个新的CompletableFuture对象,它的计算结果为原始结果或异常处理结果。

示例代码:

CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
    // 异步计算任务
    throw new RuntimeException("计算异常");
});
CompletableFuture<Integer> future2 = future.exceptionally(e -> {
    System.out.println("计算出现异常:" + e.getMessage());
    return 0;
});
int result2 = future2.get();
System.out.println(result2);

多线程结合使用

CompletableFuture可以与多线程结合使用,实现更加高效的异步编程。下面是一个简单的示例,演示了如何使用CompletableFuture和多线程实现异步计算。

public class CompletableFutureDemo {
    public static void main(String[] args) throws Exception {
        ExecutorService executorService = Executors.newFixedThreadPool(3);
        CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> {
            // 异步计算任务
            return 1 + 2;
        }, executorService);
        CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> {
            // 异步计算任务
            return 3 + 4;
        }, executorService);
        CompletableFuture<Integer> future3 = future1.thenCombineAsync(future2, (result1, result2) -> {
            // 异步计算任务
            return result1 + result2;
        }, executorService);
        int result = future3.get();
        System.out.println(result);
        executorService.shutdown();
    }
}

在上面的示例中,我们使用了ExecutorService来创建线程池,并将其传递给CompletableFuture的方法中。这样可以控制异步计算的线程池大小,避免创建太多线程导致性能下降。

总结

CompletableFuture是Java 8中新增的一个类,它实现了Future和CompletionStage接口,提供了一种更加灵活的异步编程方式。CompletableFuture可以看作是一个包含了计算结果的容器,可以在计算完成后获取结果,也可以在计算完成前执行一些操作。

CompletableFuture提供了更多的方法来处理异步计算的结果,包括获取计算结果、异步回调、异步消费、异步组合、异常处理等操作。它可以与多线程结合使用,实现更加高效的异步编程。

在使用CompletableFuture时,需要注意线程池的大小,避免创建过多线程导致性能下降。除此之外,我们还可以使用CompletableFuture来处理大量的异步任务,提高系统的并发能力和性能。

👉 💐🌸 公众号请关注 "果酱桑", 一起学习,一起进步! 🌸💐 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java中的多线程编程是一个重要的概念,它可以充分利用计算机的多个核心以提高程序的性能。在Java中,你可以使用Thread或Runnable来实现基本的线程编程。而CompletableFuture则是Java 8引入的一个强大的工具,它提供了异步编程的能力,可以更方便地处理异步任务。 下面是一个使用CompletableFuture和runAsync方法结合的例子: ```java import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; public class Main { public static void main(String[] args) { // 创建一个CompletableFuture对象 CompletableFuture<Void> future = CompletableFuture.runAsync(() -> { // 这里是你要异步执行的任务 try { // 模拟一个耗时操作 Thread.sleep(3000); System.out.println("任务执行完成"); } catch (InterruptedException e) { e.printStackTrace(); } }); // 在主线程做一些其他的工作 try { Thread.sleep(100); // 主线程休眠一下 } catch (InterruptedException e) { e.printStackTrace(); } // 等待异步任务完成,返回结果(在这个例子中为null) try { future.get(); // 注意这会阻塞,除非有并发修改,否则在正常应用场景中应避免使用 } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); } } } ``` 在这个例子中,我们创建了一个CompletableFuture对象,并使用`runAsync`方法来启动一个新的线程执行一个任务。这个任务只是一个简单的模拟耗时操作(这里使用了`Thread.sleep`)。在主线程中,我们等待异步任务完成,并获取其结果。注意,这个例子中的`future.get()`会阻塞主线程,除非有并发修改,否则在正常应用场景中应避免使用。在实际应用中,你可能需要使用更复杂的方式来处理异步任务的结果。 CompletableFuture还提供了许多其他的方法,如`thenApply`、`thenAccept`、`thenCompose`等,可以更方便地处理异步任务的结果和异常。你可以根据需要选择合适的方法来处理你的异步任务。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值