Spring/SpringBoot自定义线程池

Spring/SpringBoot自定义线程池

在 Spring/SpringBoot 中,可以使用 @Configuration 和 @Bean 去设置线程池,用 @Value 去做线程池的参数配置。

依赖包:

引用 google 的 guava包。

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>19.0</version>
</dependency>

线程池配置:

import com.google.common.util.concurrent.ThreadFactoryBuilder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.concurrent.*;



@Configuration
public class ThreadPoolExecutorConfig {

    /**
     * 核心线程数, :冒号后面是默认值
     */
    @Value("${executor.core.pool.size:20}")
    private int corePoolSize;

    /**
     * 最大线程数, :冒号后面是默认值
     */
    @Value("${executor.max.pool.size:100}")
    private int maxPoolSize;

    /**
     * 没有任务执行时,线程的存活时间
     */
    @Value("${executor.keep.alive.time:2}")
    private int keepAliveTime;

    /**
     * 阻塞队列长度
     */
    @Value("${executor.blocking.queue.size:200}")
    private int blockingQueueSize;


    /**
     * 使用 @Bean 指定线程池的名称
     *
     */
    @Bean("myExecutor")
    public Executor myExecutor() {

        //阻塞队列长度
        BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(blockingQueueSize);

        //创建线程或线程池时指定有意义的线程名称,方便出错时回溯。名称如果过长,会被截断。
        ThreadFactory threadFactory = new ThreadFactoryBuilder()
                .setNameFormat("my-executor-%d").build();
        //可以自定义拒绝策略,也可以不加这个参数,构造方法会直接用默认的拒绝策略
        ThreadPoolExecutor.AbortPolicy abortPolicy = new ThreadPoolExecutor.AbortPolicy();

        return new ThreadPoolExecutor(corePoolSize, maxPoolSize,
                keepAliveTime, TimeUnit.SECONDS, workQueue, threadFactory, abortPolicy);


    }


    /**
     * 不同的业务,有时可以使用不同的线程池、不同的配置。
     * 如果核心业务跟普通业务,用同一个线程池,普通业务可能会占用过多的线程数,导致核心业务受影响。
     */
    @Bean("myExecutor2")
    public Executor myExecutor2() {

        //阻塞队列长度
        BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(blockingQueueSize);

        //创建线程或线程池时指定有意义的线程名称,方便出错时回溯。
        ThreadFactory threadFactory = new ThreadFactoryBuilder()
                .setNameFormat("my-executor2-%d").build();
        //可以自定义拒绝策略,也可以不加这个参数,构造方法会直接用默认的拒绝策略
        ThreadPoolExecutor.AbortPolicy abortPolicy = new ThreadPoolExecutor.AbortPolicy();

        return new ThreadPoolExecutor(corePoolSize, maxPoolSize,
                keepAliveTime, TimeUnit.SECONDS, workQueue, threadFactory, abortPolicy);
    }

}

配置参数:

可以写到配置中心里面,如果没有配置中心,放到 propeties 文件也行。

executor.core.pool.size=20
executor.max.pool.size=100
executor.keep.alive.time=2
executor.blocking.queue.size=200

使用线程池:

日志框架自行补充,可以在Service类上面用 lombok的 @Slf4j 注解,也可以用其他的日志。

@Service
@Slf4j
public class MyService {

    @Resource(name = "myExecutor")
    private Executor executor;

    public void execute() {
        executor.execute(() -> log.info("线程池执行任务."));

    }

}

运行,查看日志:

INFO 18876 --- [ my-executor-0] com.example.demo.threadpool.MyService    : 线程池执行任务.

可以看到 线程池已经执行任务。日志中的 线程名称 是 my-executor 开头的。

把MyService 类中的 (name = "myExecutor") 换成 (name = "myExecutor2") ,再次运行,查看日志:

INFO 18876 --- [ my-executor2-0] com.example.demo.threadpool.MyService    : 线程池执行任务.

可以看到日志,线程池已经执行任务。 线程名称 变成 了 my-executor2 开头的了。

创建线程或线程池时,指定有意义的线程名称,方便出错时回溯。

Spring / 普通Java项目的自定义线程池

详情见:https://www.cnblogs.com/expiator/p/17140760.html

相关推荐
哎呦没29 分钟前
大学生就业招聘:Spring Boot系统的架构分析
java·spring boot·后端
_.Switch1 小时前
Python Web 应用中的 API 网关集成与优化
开发语言·前端·后端·python·架构·log4j
编程、小哥哥1 小时前
netty之Netty与SpringBoot整合
java·spring boot·spring
IT学长编程2 小时前
计算机毕业设计 玩具租赁系统的设计与实现 Java实战项目 附源码+文档+视频讲解
java·spring boot·毕业设计·课程设计·毕业论文·计算机毕业设计选题·玩具租赁系统
杨哥带你写代码2 小时前
足球青训俱乐部管理:Spring Boot技术驱动
java·spring boot·后端
AskHarries3 小时前
读《show your work》的一点感悟
后端
A尘埃3 小时前
SpringBoot的数据访问
java·spring boot·后端
yang-23073 小时前
端口冲突的解决方案以及SpringBoot自动检测可用端口demo
java·spring boot·后端
Marst Code3 小时前
(Django)初步使用
后端·python·django
代码之光_19803 小时前
SpringBoot校园资料分享平台:设计与实现
java·spring boot·后端