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

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.如何设置核心线程数

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

  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. Selenium的基本api

    1.打开浏览器的驱动,以chrome为例 from selenium import webdriver #chrome驱动 driver = webdriver.Chrome(executable_p ...

  2. selenium之下拉菜单列表定位

    下拉菜单列表定位>>使用Select类定位 from selenium.webdriver.support.ui import Select #导入Select类 select=Selec ...

  3. 微软成为PostgreSQL主要贡献者

    微软成为PostgreSQL主要贡献者 微软对PostgreSQL贡献的很多新功能都来自于客户在使用微软Azure上的PostgreSQL管理实例数据库,所以这些新功能都来自于真实的客户需求 微软对P ...

  4. Python中numpy出现has no attribute '_no_nep50_warning'错误的一个解决方案

      本文介绍在Python中,numpy库出现报错module 'numpy' has no attribute '_no_nep50_warning'的解决方法.   一次,在运行一个Python代 ...

  5. 微软用它取代了`Nginx`吞吐量提升了百分之八十!

    Azure应用服务用YARP取代了Nginx,获得了80%以上的吞吐量.他们每天处理160B多个请求(1.9 m RPS).这是微软的一项了不起的技术创新. 首先我们来介绍一下什么是Yarp Yarp ...

  6. python中,如何优雅的解析和管理命令行参数

    背景 我们在编写python程序时,程序中经常会提供多种功能或者模式,在实际使用时根据不同的参数使用不同的功能.那么如何获取命令行传入进来的参数呢? 一般方法 一般情况下,我们会使用 sys 模块,如 ...

  7. 斯坦福 UE4 C++ ActionRoguelike游戏实例教程 02.AI自定义任务和观察器中断

    斯坦福课程 UE4 C++ ActionRoguelike游戏实例教程 0.绪论 概述 本文章对应课程第十一章 42节.这篇文章会进一步地为AI添加新功能,创建自定义任务,允许AI发射子弹,并且讲解观 ...

  8. [活动(深圳)] .NET Love AI 之 .NET Conf China 2023 Party 深圳

    中国.NET 社区2023年12月16日 在北京成功举办了.NET Conf China 2023,虽然北京飘起雪,依然挡不住想要参加活动的全国各地的.NET开发兄弟姐妹的热情.大家可以通过大会精彩照 ...

  9. 构建万物互联,华为云IoT+鸿蒙重燃物体感知

    摘要:鸿蒙的出现,让硬件.软件行业面临着变革与重构的洪流,但激流勇进中,也潜藏着巨大机遇.物联网设备与鸿蒙结合成为必然趋势,本文将解读华为云IoT+鸿蒙如何强强联合,为物联网行业提供新的思路和方法. ...

  10. 如何利用CANN DVPP进行图片的等比例缩放?

    摘要:介绍如何用昇腾AI处理器上的DVPP单元进行,图像的等比例缩放,保证图像不变形. 本文分享自华为云社区<CANN DVPP进行图片的等比例缩放>,作者:马城林 . 1. 为什么需要进 ...