本文为博主原创,转载请注明出处:

1. 使用 ThreadPoolTaskExecutor  封装自定义配置的线程池Bean

  ThreadPoolTaskExecutor 是Spring 中封装的一个类,spring boot中常用 ThreadPoolTaskExecutor 创建线程池,并把它注入到 IOC 容器中,从而可以全局进行使用。

   如下为使用 ThreadPoolTaskExecutor  创建的自定义配置的 线程池类:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import java.util.concurrent.Executor; @Configuration
@EnableAsync
public class ThreadPoolExecutorConfig { @Bean(name="threadPoolExecutor")
public Executor threadPoolExecutor(){
ThreadPoolTaskExecutor threadPoolExecutor = new ThreadPoolTaskExecutor();
int processNum = Runtime.getRuntime().availableProcessors(); // 返回可用处理器的Java虚拟机的数量
int corePoolSize = (int) (processNum / (1 - 0.2));
int maxPoolSize = (int) (processNum / (1 - 0.5));
threadPoolExecutor.setCorePoolSize(corePoolSize); // 核心池大小
threadPoolExecutor.setMaxPoolSize(maxPoolSize); // 最大线程数
threadPoolExecutor.setQueueCapacity(maxPoolSize * 1000); // 队列程度
threadPoolExecutor.setThreadPriority(Thread.MAX_PRIORITY);
threadPoolExecutor.setDaemon(false);
threadPoolExecutor.setKeepAliveSeconds(300);// 线程空闲时间
threadPoolExecutor.setThreadNamePrefix("test-Executor-"); // 线程名字前缀
return threadPoolExecutor;
}
}

  @EnableAsync是与@Async配合使用,用于执行异步任务

  使用示例:

@Service
public class SpringExecutorTest {
@Autowired
private Executor threadPoolExecutor; public void test(){
AtomicInteger num = new AtomicInteger(0);
for (int i = 0; i < 5; i++) {
threadPoolExecutor.execute(()->{
num.incrementAndGet();
});
}
System.out.println(num.get());
}
}

2. 与 @Async 注解使用

    @Async("threadPoolExecutor")
public void asyncTest(){
log.error("threadPoolExecutor asyncTest start");
}

  需要注意的是,在使用 @Async 注解时,想使用自定义的 Executor 线程池配置,则需要在 @Async 注解上声明线程池的名称,否则会使用默认的线程池配置。

  若想在使用@Async 注解时,不显示声明线程池,且使用定义线程池的配置,可采用以下方式进行配置:

import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import java.lang.reflect.Method;
import java.util.concurrent.Executor; @Slf4j
@Configuration
public class NativeAsyncTaskExecutePool implements AsyncConfigurer {
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor threadPoolExecutor = new ThreadPoolTaskExecutor();
int processNum = Runtime.getRuntime().availableProcessors(); // 返回可用处理器的Java虚拟机的数量
int corePoolSize = (int) (processNum / (1 - 0.2));
int maxPoolSize = (int) (processNum / (1 - 0.5));
threadPoolExecutor.setCorePoolSize(corePoolSize); // 核心池大小
threadPoolExecutor.setMaxPoolSize(maxPoolSize); // 最大线程数
threadPoolExecutor.setQueueCapacity(maxPoolSize * 1000); // 队列程度
threadPoolExecutor.setThreadPriority(Thread.MAX_PRIORITY);
threadPoolExecutor.setDaemon(false);
threadPoolExecutor.setKeepAliveSeconds(300);// 线程空闲时间
threadPoolExecutor.setThreadNamePrefix("test-Executor-"); // 线程名字前缀
return threadPoolExecutor;
} /**
* 异步任务中异常处理
* @return
*/
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new AsyncUncaughtExceptionHandler() {
@Override
public void handleUncaughtException(Throwable arg0, Method arg1, Object... arg2) {
log.error("=========================="+arg0.getMessage()+"=======================", arg0);
log.error("exception method:"+arg1.getName());
}
};
}
}

  当使用以上的方式时,可在使用 @Async 注解时,不用显示生命线程池的方式就可以使用自定义的线程池。

3.如何设置核心线程数

  对于ThreadPoolTaskExecutor的corePoolSize,一般来说可以根据任务的性质、数量、执行时间等因素进行灵活调整,具体的配置需要根据实际情况来决定。这里提供一些核心线程数设置的建议:

  1. 根据任务的性质来设置corePoolSize。

  如果任务量较少且每个任务都非常耗时,可以适当减少核心线程数以节省资源,例如将corePoolSize设置为2-3;如果有大量的耗时短的任务,可以适当增加核心线程数,例如将corePoolSize设置为10-20等。

  1. 根据CPU核心数来设置corePoolSize。

  通常情况下,corePoolSize建议设置为CPU核心数的2倍,这样可以保证资源的最大利用。但需要注意的是,当任务的处理时间较长时(例如IO操作),可以适当增加corePoolSize以避免线程空闲等待。

学习ThreadPoolExecutor 更多可以参考这篇文章:Java线程池实现原理及其在美团业务中的实践

Spring boot 自定义ThreadPoolTaskExecutor 线程池并进行异步操作的更多相关文章

  1. spring boot自定义线程池以及异步处理

    spring boot自定义线程池以及异步处理@Async:什么是线程池?线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务.线程池线程都是后台线程.每个线程都使 ...

  2. Spring Boot 自定义kafka 消费者配置 ContainerFactory最佳实践

    Spring Boot 自定义kafka 消费者配置 ContainerFactory最佳实践 本篇博文主要提供一个在 SpringBoot 中自定义 kafka配置的实践,想象这样一个场景:你的系统 ...

  3. ThreadPoolTaskExecutor线程池创建

    package com.xx.xx.config; import java.util.concurrent.ThreadPoolExecutor; import org.slf4j.Logger; i ...

  4. Spring Boot [使用 Druid 数据库连接池]

    导读 最近一段时间比较忙,以至于很久没有更新Spring Boot系列文章,恰好最近用到Druid, 就将Spring Boot 使用 Druid作为数据源做一个简单的介绍. Druid介绍: Dru ...

  5. Spring Boot自定义配置与加载

    Spring Boot自定义配置与加载 application.properties主要用来配置数据库连接.日志相关配置等.除了这些配置内容之外,还可以自定义一些配置项,如: my.config.ms ...

  6. Spring Boot 2.X(四):Spring Boot 自定义 Web MVC 配置

    0.准备 Spring Boot 不仅提供了相当简单使用的自动配置功能,而且开放了非常自由灵活的配置类.Spring MVC 为我们提供了 WebMvcConfigurationSupport 类和一 ...

  7. java基础|自定义java线程池

    线程池创建的参数 在创建线程的各种方式中我们有讲到过通过创建线程池来完成异步操作,但实际上jdk提供的Executors来创建线程池都还有些缺陷,线程池有以下几个参数: 代码节选自源码ThreadPo ...

  8. 十、自定义ThreadPoolExecutor线程池

    自定义ThreadPoolExecutor线程池 自定义线程池需要遵循的规则 [1]线程池大小的设置 1.计算密集型: 顾名思义就是应用需要非常多的CPU计算资源,在多核CPU时代,我们要让每一个CP ...

  9. Spring Boot自定义Redis缓存配置,保存value格式JSON字符串

    Spring Boot自定义Redis缓存,保存格式JSON字符串 部分内容转自 https://blog.csdn.net/caojidasabi/article/details/83059642 ...

  10. 玩转Spring Boot 自定义配置、导入XML配置与外部化配置

    玩转Spring Boot 自定义配置.导入XML配置与外部化配置       在这里我会全面介绍在Spring Boot里面如何自定义配置,更改Spring Boot默认的配置,以及介绍各配置的优先 ...

随机推荐

  1. SpringSecurity入门(SSM版)

    1. 简介 Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架.它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Sp ...

  2. Redis存储商品热度

    项目中有一个需求,就是可以根据商品的热度进行排序 起初想着使用string类型来存储如: sku:hotscore:商品的ID 但是这回有个问题,当商品数量多了那k-v岂不是得炸了,维护起来也非常不方 ...

  3. 35. 干货系列从零用Rust编写负载均衡及代理,代理服务器的源码升级改造

    wmproxy wmproxy已用Rust实现http/https代理, socks5代理, 反向代理, 静态文件服务器,四层TCP/UDP转发,七层负载均衡,内网穿透,后续将实现websocket代 ...

  4. 启发式搜索(heuristic search)———A*算法

    在宽度优先和深度优先搜索里面,我们都是根据搜索的顺序依次进行搜索,可以称为盲目搜索,搜索效率非常低. 而启发式搜索则大大提高了搜索效率,由这两张图可以看出它们的差别: (左图类似与盲搜,右图为启发式搜 ...

  5. 【最佳实践】京东小程序-LBS业务场景的性能提升

    一.前言 1.1 京东LBS门详业务介绍 京东LBS门详目前已经支持了仓网.药急送.天选.小时达POP多种业务,并且具备了多端的能力,一套代码可以在京东app.健康app.微信小程序中运行,一定程度上 ...

  6. 2023计算机保研经验贴 直博向(南大cs,计算所,科大高研院,浙大cs,交大cs,国科cs,北大cs,清华cs)

    写在前面 本人作为普通选手,只能将个人经验分享一二,不能代表其他人的想法和意见,望路过的大佬们高抬贵手-,如果有相关老师或者同学认为我违反了保密条例请与我私信联系,我会第一时间删除相关内容. 个人情况 ...

  7. 华企盾DSC编辑文件不加密常见问题

    1.先查看客户端日志主进程是否是加密进程.日志中是不是勾选智能半透明.加密类型是否有添加 2.用procmon监控保存的文件找出writefile的进程是否有添加,进程树是否有父进程,加密类型是否正确 ...

  8. 数字孪生与GIS结合,为智慧交通带来的改变

    在当代社会,交通问题已经成为城市发展中的一个重要挑战.交通拥堵.安全隐患.环境污染等问题给人们的出行带来了许多不便和困扰.然而,随着数字孪生技术与地理信息系统(GIS)的融合,我们迎来了智慧交通的新时 ...

  9. 【C#】【IO】【实例】统计多个文件夹下的图片

    因工作需要繁琐的进行同一目录多个文件夹下的图片统计,便使用代码来解决. 需求:统计的是多少个文件夹包含了图片,并非是统计有多少张图. 我们先用Python来创建一个现场环境(巩固巩固py知识): 1 ...

  10. Shell的概念、shebang、bash的概念

    什么是shell shell的作用是 解释执行用户输入的命令或程序等 用户输入一条命令,shell就解释一条 键盘输入命令,Linux给与响应的方式,称之为交互式 linux的计算机是如何跟用户进行交 ...