动态线程池与CompletableFuture类

动态线程池解析与CompletableFuture类
一、动态线程池的需求

​ 我们都知道线程池的引入,使得线程不再频繁创建与销毁,节省了系统的性能。线程池的引入,让线程得到复用,响应速度也更快。当我们使用ThreadPoolExecutor创建线程池时,需要指定参数,那么我们创建的线程池的规模一般是固定的。然而现实生活中,需求总是在变化的,来自用户的流量也是时刻在变化。动态线程池可以根据流量的不同,从而调节线程池中的某些参数。在流量洪峰时增加线程,在流量低谷时减少线程。动态线程池,可以适应并发量的突发性,以及提高系统的可伸缩性。

二、动态线程池的基础

​ 通过ThreadPoolExecutor创建线程池,corePoolSize等参数确定线程池的特性。JDK中的ThreadPoolExecutor类提供了多个参数的set方法,如下图所示:

在这里插入图片描述

​ 通过set方法,可以调整线程池的核心线程数,最大线程数,存活时间,线程工厂和拒绝策略。这些public的set方法是动态线程池实现的基础。

三、动态线程池的实现

​ 虽然上述的set方法,可以实现对线程池参数的更改,但每次修改都需要重新发布,这是一件非常麻烦的事情。我们可以考虑将线程池中的参数从代码中迁移到分布式配置中心中,基于配置中心对线程池ThreadPoolExecutor做一些扩展,实现对运行中线程池参数的动态修改,实时生效。Apollo是携程框架部门研发的分布式配置中心,能够集中管理应用不同集群的配置,在配置修改后能够实时推送到应用端。下面说一下使用的步骤:

  1. 下载Apollo并整合SpringBoot,导入Maven依赖,配置application.yml文件,启动类上加@EnableApolloConfig。
  2. 在Apollo服务端发布一个线程池配置。
  3. 编写核心代码类。
  4. 线程测试执行。
四、CompletableFuture
4.1 Future

​ CompletableFuture是Future的增强,要明白CompleteFuture,得先了解Future。Future是对Runnable或Callable任务结果进行取消、查询状态、获取结果。在实际中,使用FutureTask创建Future。将 Callable 实例当作 FutureTask 构造函数的参数,生成 FutureTask 的对象,放到线程池中或另起线程去执行,最后还可以通过 FutureTask 获取任务执行的结果,代码如下所示:

//子线程任务
public class CallableTask implements Callable<Integer> {
    @Override
    public Integer call() throws Exception {
        System.out.println("线程正在计算");
        int sum = 0;
        for (int i = 0; i < 10; i++) {
            sum += i;
        }
        return sum;
    }
}
public class FutureTaskDemo {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
            CallableTask task = new  CallableTask();
            //构建futureTask
            FutureTask<Integer> futureTask = new FutureTask<>(task);
            //作为Runnable入参
            new Thread(futureTask).start();
            System.out.println("task运行结果:" + futureTask.get());

    }
}

执行结果:

在这里插入图片描述

4.2 CompletableFuture

​ 事实上,Future表示一个异步计算的结果。在异步计算中,Future确实是个非常好用的接口。简单的任务,用Future获取结果还好,但我们并行提交的多个异步任务,往往并不是独立的,很多时候业务逻辑处理存在串行、并行、聚合的关系。如果要我们手动用 Fueture 实现,是非常麻烦的。CompletableFuture是jdk8的新特性,实现了对任务的编排能力。借助这项能力,我们可以轻松地组织不同任务的运行顺序、规则以及方式。它能够创建异步任务、进行异步回调处理、也可以进行多任务组合处理,常用方法如下图所示:

在这里插入图片描述

这里展示一个多任务处理的例子,使用thenCombine方法,将任务1(cf1)与任务2(cf2)联合起来,进行任务3(cf3),代码如下:

public class CompleteFutureDemo {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        CompletableFuture<Integer> cf1 = CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread() + " 任务1运行中....");
            return 2;
        });
        CompletableFuture<Integer> cf2 = CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread() + " 任务2运行中....");
            return 3;
        });
        CompletableFuture<Integer> cf3 = cf1.thenCombine(cf2, (a, b) -> {
            System.out.println(Thread.currentThread() + " 任务3运行中....");
            return a + b;
        });
        System.out.println("cf3结果->" + cf3.get());
    }
}

执行结果:

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot中,可以使用线程池CompletableFuture一起工作来提高应用程序的并发性能和响应性。 首先,你可以使用`ThreadPoolTaskExecutor`来创建一个线程池。在Spring Boot中,你可以通过在应用程序的配置文件中添加以下属性来配置线程池: ```properties # 线程池配置 spring.task.execution.pool.core-size=10 spring.task.execution.pool.max-size=20 spring.task.execution.pool.queue-capacity=1000 spring.task.execution.pool.thread-name-prefix=my-thread- ``` 这个配置将创建一个具有10个核心线程和20个最大线程的线程池,以及一个容量为1000的工作队列。你可以根据你的需求进行调整。 接下来,你可以使用CompletableFuture来异步执行任务。CompletableFuture是一个Java 8引入的,可以用于进行异步编程。你可以使用它的`supplyAsync()`方法来异步执行一个任务,并返回一个Future对象。 ```java CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> { // 执行异步任务 return "任务结果"; }); ``` 你可以在CompletableFuture对象上调用`thenApply()`、`thenAccept()`或`thenRun()`等方法来处理异步任务的结果或执行其他操作。这些方法接收一个函数作为参数,用于处理任务的结果。 ```java future.thenApply(result -> { // 处理任务结果 return "处理后的结果"; }); ``` 在处理任务结果时,你可以利用线程池来执行一些耗时的操作,以避免阻塞主线程。你可以通过在CompletableFuture对象上调用`thenApplyAsync()`、`thenAcceptAsync()`或`thenRunAsync()`方法来异步执行操作。 ```java future.thenApplyAsync(result -> { // 异步处理任务结果 return "处理后的结果"; }, executor); ``` 在这里,`executor`是你之前配置的线程池对象。 通过将线程池CompletableFuture结合起来使用,你可以实现更高效的并发处理和响应性能。记得根据实际需求调整线程池的配置,以避免资源浪费或线程饥饿等问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值