当前位置: 首页 > article >正文

Spring Boot 中多线程工具类的配置与使用:基于 YAML 配置文件

文章目录

      • Spring Boot 中多线程工具类的配置与使用:基于 YAML 配置文件
      • 1. 为什么需要多线程工具类?
      • 2. 实现步骤
        • 2.1 添加依赖
        • 2.2 配置线程池参数
        • 2.3 创建配置类
        • 2.4 创建线程池工具类
        • 2.5 使用线程池工具类
        • 2.6 测试线程池工具类
      • 3. 配置文件的灵活性
      • 4. 总结


Spring Boot 中多线程工具类的配置与使用:基于 YAML 配置文件

在现代软件开发中,多线程编程是提高系统性能和并发处理能力的重要手段。Spring Boot 作为一款流行的 Java 开发框架,提供了强大的多线程支持。本文将详细介绍如何在 Spring Boot 中结合 YAML 配置文件,实现一个灵活、可配置的多线程工具类。


1. 为什么需要多线程工具类?

在多线程编程中,直接使用 ThreadExecutorService 可能会导致以下问题:

  • 资源浪费:频繁创建和销毁线程会消耗大量系统资源。
  • 难以管理:线程的生命周期和状态难以监控和维护。
  • 配置不灵活:线程池的参数(如核心线程数、队列容量等)硬编码在代码中,难以动态调整。

通过封装一个多线程工具类,并结合 YAML 配置文件,可以解决上述问题,使多线程编程更加高效和灵活。


2. 实现步骤

2.1 添加依赖

pom.xml 中添加 Spring Boot 的依赖:

<dependencies>
    <!-- Spring Boot Starter -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>

    <!-- Spring Boot Configuration Processor -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-configuration-processor</artifactId>
        <optional>true</optional>
    </dependency>
</dependencies>
2.2 配置线程池参数

application.yml 中定义线程池的配置参数:

thread-pool:
  core-pool-size: 10 # 核心线程数
  max-pool-size: 20 # 最大线程数
  queue-capacity: 100 # 任务队列容量
  keep-alive-time: 60 # 线程空闲时间(秒)
  thread-name-prefix: "custom-thread-" # 线程名称前缀
2.3 创建配置类

通过 @ConfigurationProperties 注解将 YAML 文件中的配置映射到 Java 类中:

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties(prefix = "thread-pool")
public class ThreadPoolProperties {
    private int corePoolSize;
    private int maxPoolSize;
    private int queueCapacity;
    private long keepAliveTime;
    private String threadNamePrefix;

    // Getters and Setters
    public int getCorePoolSize() {
        return corePoolSize;
    }

    public void setCorePoolSize(int corePoolSize) {
        this.corePoolSize = corePoolSize;
    }

    public int getMaxPoolSize() {
        return maxPoolSize;
    }

    public void setMaxPoolSize(int maxPoolSize) {
        this.maxPoolSize = maxPoolSize;
    }

    public int getQueueCapacity() {
        return queueCapacity;
    }

    public void setQueueCapacity(int queueCapacity) {
        this.queueCapacity = queueCapacity;
    }

    public long getKeepAliveTime() {
        return keepAliveTime;
    }

    public void setKeepAliveTime(long keepAliveTime) {
        this.keepAliveTime = keepAliveTime;
    }

    public String getThreadNamePrefix() {
        return threadNamePrefix;
    }

    public void setThreadNamePrefix(String threadNamePrefix) {
        this.threadNamePrefix = threadNamePrefix;
    }
}
2.4 创建线程池工具类

在工具类中注入 ThreadPoolProperties,并根据配置创建线程池:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.concurrent.*;

@Component
public class ThreadPoolUtil {

    private ThreadPoolExecutor threadPool;

    @Autowired
    private ThreadPoolProperties threadPoolProperties;

    /**
     * 初始化线程池
     */
    @PostConstruct
    public void init() {
        threadPool = new ThreadPoolExecutor(
                threadPoolProperties.getCorePoolSize(),
                threadPoolProperties.getMaxPoolSize(),
                threadPoolProperties.getKeepAliveTime(),
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(threadPoolProperties.getQueueCapacity()),
                new ThreadFactory() {
                    private final AtomicInteger threadNumber = new AtomicInteger(1);

                    @Override
                    public Thread newThread(Runnable r) {
                        return new Thread(r, threadPoolProperties.getThreadNamePrefix() + threadNumber.getAndIncrement());
                    }
                },
                new ThreadPoolExecutor.AbortPolicy() // 拒绝策略:直接抛出异常
        );
    }

    /**
     * 提交任务(Runnable)
     *
     * @param task 任务
     */
    public void execute(Runnable task) {
        threadPool.execute(task);
    }

    /**
     * 提交任务(Callable)
     *
     * @param task 任务
     * @param <T>  返回值类型
     * @return Future 对象
     */
    public <T> Future<T> submit(Callable<T> task) {
        return threadPool.submit(task);
    }

    /**
     * 关闭线程池(等待所有任务完成)
     */
    @PreDestroy
    public void shutdown() {
        if (threadPool != null) {
            threadPool.shutdown();
            try {
                if (!threadPool.awaitTermination(60, TimeUnit.SECONDS)) {
                    threadPool.shutdownNow();
                }
            } catch (InterruptedException e) {
                threadPool.shutdownNow();
                Thread.currentThread().interrupt();
            }
        }
    }

    /**
     * 获取线程池状态
     *
     * @return 线程池状态信息
     */
    public String getThreadPoolStatus() {
        if (threadPool == null) {
            return "Thread pool is not initialized.";
        }
        return String.format(
                "Pool Status: [CorePoolSize: %d, ActiveThreads: %d, CompletedTasks: %d, QueueSize: %d]",
                threadPool.getCorePoolSize(),
                threadPool.getActiveCount(),
                threadPool.getCompletedTaskCount(),
                threadPool.getQueue().size()
        );
    }
}
2.5 使用线程池工具类

在业务代码中注入 ThreadPoolUtil,并提交任务:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class TaskService {

    @Autowired
    private ThreadPoolUtil threadPoolUtil;

    public void runTask() {
        // 提交 Runnable 任务
        threadPoolUtil.execute(() -> {
            System.out.println("Runnable task is running.");
        });

        // 提交 Callable 任务并获取结果
        Future<String> future = threadPoolUtil.submit(() -> {
            Thread.sleep(1000);
            return "Callable task result";
        });

        try {
            System.out.println("Callable task result: " + future.get());
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }

        // 打印线程池状态
        System.out.println(threadPoolUtil.getThreadPoolStatus());
    }
}
2.6 测试线程池工具类

编写单元测试,验证线程池的功能:

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class ThreadPoolUtilTest {

    @Autowired
    private TaskService taskService;

    @Test
    public void testThreadPool() {
        taskService.runTask();
    }
}

3. 配置文件的灵活性

通过 application.yml 配置文件,可以灵活调整线程池的参数,而无需修改代码。例如:

  • 调整核心线程数:

    thread-pool:
      core-pool-size: 20
    
  • 调整任务队列容量:

    thread-pool:
      queue-capacity: 200
    
  • 调整线程名称前缀:

    thread-pool:
      thread-name-prefix: "app-thread-"
    

4. 总结

通过将线程池的配置参数提取到 application.yml 中,并结合 Spring Boot 的依赖注入机制,我们可以实现一个灵活、可配置的多线程工具类。这种方式不仅提高了代码的可维护性,还能根据实际需求动态调整线程池的行为,是 Spring Boot 项目中管理多线程任务的推荐做法。希望本文能帮助你更好地理解和应用 Spring Boot 中的多线程编程技术!


http://www.kler.cn/a/557017.html

相关文章:

  • 脚本实战第一发:所有的请求都可以被 Python 模拟
  • 论文笔记-WSDM2025-ColdLLM
  • 外盘期货数据分析新视角:分钟级高频数据解析
  • 七、敏捷开发工具:持续集成与部署工具
  • 使用Python PyTorch框架+卷积神经网络(CNN)构造基于超图的综合立体交通超网络模型
  • 获取钉钉OA审批数据
  • C++——AVL平衡二叉树
  • AI大模型-提示工程学习笔记15—主动提示 (Active Prompt)
  • 1.21作业
  • 汽车自动驾驶辅助L2++是什么?
  • 数字人面试
  • STM32 HAL库USART串口DMA IDLE中断编程:避坑指南
  • 机试刷题_编辑距离(二)【python】
  • 【Flink 实战】Flink 中 Akka 通信与内存占用分析
  • 【设计模式】【创建型模式】单例模式(Singleton)
  • golang时间相关函数总结
  • ZLG嵌入式笔记 | 为什么你的网卡工作会不正常?(上
  • Typora的Github主题美化
  • Service Mesh在爱奇艺的落地实践:架构、运维与扩展
  • 微服务即时通信系统---(二)框架学习