springboot原生线程池使用、异步处理

SpringBoot实现异步调用的方法 方法优点缺点。 阅读详情

1、启动类添加注解,开启异步支持

@EnableAsync//开启异步处理支持,开启springboot线程池

2、配置文件配置属性(我是自定义的配置文件,config.properties,也可以配置在application.properties中)

#线程池配置
#核心线程池大小
async.pool.corePoolSize=20
#最大线程数
async.pool.maxPoolSize=40
#活跃时间
async.pool.keepAliveSeconds=300
#队列容量
async.pool.queueCapacity=50

3、实现原生异步配置类,并配置自定义参数

AsyncExecuteThreadPool

其中:@Slf4j是用来打印日志的。@PropertySource(value="classpath:config.properties")是用来读取自定义配置文件的,如果配置信息放在了application.properties中无需使用。

package com.gili.CPMasterController.common.async;

import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.lang.reflect.Method;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * 原生(Spring)异步任务线程池装配类
 * Created by groot
 */
@Slf4j
@Configuration
@PropertySource(value="classpath:config.properties")
public class AsyncExecuteThreadPool implements AsyncConfigurer {

    @Value("${async.pool.corePoolSize}")
    private int corePoolSize;//核心线程池大小

    @Value("${async.pool.maxPoolSize}")
    private int maxPoolSize;//最大线程数

    @Value("${async.pool.keepAliveSeconds}")
    private int keepAliveSeconds;//活跃时间

    @Value("${async.pool.queueCapacity}")
    private int queueCapacity;//队列容量

    @Override
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        //核心线程池大小
        executor.setCorePoolSize(corePoolSize);
        //最大线程数
        executor.setMaxPoolSize(maxPoolSize);
        //队列容量
        executor.setQueueCapacity(queueCapacity);
        //活跃时间
        executor.setKeepAliveSeconds(keepAliveSeconds);
        //线程名字前缀
        executor.setThreadNamePrefix("CP Thread-");

        // setRejectedExecutionHandler:当pool已经达到max size的时候,如何处理新任务
        // CallerRunsPolicy:不在新线程中执行任务,而是由调用者所在的线程来执行
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.initialize();
        return executor;
    }


    /**
     *  异步任务中异常处理
     * @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());
            }
        };
    }
}

4、线程池的使用,编写异步任务业务类(注意:异步方法不能与被调用的异步方法在同一个类中,否则异步无效)

AsyncTaskServiceDemo
package com.gili.CPMasterController.common.async;

import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

/**
 * @Author : groot
 * 2019年4月11日 13:28:58
 *  异步执行线程池获取线程demo
 *  注意:异步方法不能与被调用的异步方法在同一个类中,否则异步无效
 *  使用方法:1、定义实现业务逻辑的方法如:doTask(int i)
 *            2、在方法上架注解 @Async,这样就会在执行方法时从原生线程池中获取线程来异步执行此方法
 */
@Service
@Slf4j
public class AsyncTaskServiceDemo {

    @Async
    public void doTask(int i) throws InterruptedException{
        log.info("Task-"+i+" started.");
        if(i%3==0){
            log.info("i "+i+" sleep start...");
            Thread.sleep(200);
            log.info("i "+i+" sleep end...");
        }
    }
}

5、测试

在测试类中添加测试方法

package com.gili.CPMasterController;

import com.gili.CPMasterController.common.async.AsyncTaskServiceDemo;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.concurrent.ExecutionException;

@RunWith(SpringRunner.class)
@SpringBootTest
@Slf4j
public class CPApplicationTests {

    @Autowired
    AsyncTaskServiceDemo asyncTask;

    /**
     * 线程异步调用处理测试
     * @throws InterruptedException
     * @throws ExecutionException
     */
    @Test
    public void AsyncTaskNativeTest() throws InterruptedException, ExecutionException {

        for (int i = 0; i < 20; i++) {
            asyncTask.doTask(i);
        }
        log.info("All tasks finished.");
    }

}

6、执行测试方法AsyncTaskNativeTest()得到以下日志:

 

14:00:37.434 [main] DEBUG o.s.t.c.s.AbstractDirtiesContextTestExecutionListener - Before test method: context [DefaultTestContext@398dada8 testClass = CPApplicationTests, testInstance = com.gili.CPMasterController.CPApplicationTests@17d816b3, testMethod = AsyncTaskNativeTest@CPApplicationTests, testException = [null], mergedContextConfiguration = [WebMergedContextConfiguration@7cb502c testClass = CPApplicationTests, locations = '{}', classes = '{class com.gili.CPMasterController.Application}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true}', contextCustomizers = set[org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@4988d8b8, org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@609cd4d8, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@13b6aecc, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@49e5f737], resourceBasePath = 'src/main/webapp', contextLoader = 'org.springframework.boot.test.context.SpringBootContextLoader', parent = [null]], attributes = map['org.springframework.test.context.web.ServletTestExecutionListener.activateListener' -> true, 'org.springframework.test.context.web.ServletTestExecutionListener.populatedRequestContextHolder' -> true, 'org.springframework.test.context.web.ServletTestExecutionListener.resetRequestContextHolder' -> true]], class annotated with @DirtiesContext [false] with mode [null], method annotated with @DirtiesContext [false] with mode [null].
14:00:37.445 [main] DEBUG o.s.t.c.c.DefaultCacheAwareContextLoaderDelegate - Retrieved ApplicationContext from cache with key [[WebMergedContextConfiguration@7cb502c testClass = CPApplicationTests, locations = '{}', classes = '{class com.gili.CPMasterController.Application}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true}', contextCustomizers = set[org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@4988d8b8, org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@609cd4d8, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@13b6aecc, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@49e5f737], resourceBasePath = 'src/main/webapp', contextLoader = 'org.springframework.boot.test.context.SpringBootContextLoader', parent = [null]]]
14:00:37.445 [main] DEBUG o.springframework.test.context.cache - Spring test ApplicationContext cache statistics: [DefaultContextCache@40a8a26f size = 1, maxSize = 32, parentContextCount = 0, hitCount = 2, missCount = 1]
14:00:38.392 [main] INFO  o.s.s.c.ThreadPoolTaskExecutor - Initializing ExecutorService
14:00:38.430 [CP Thread-11] INFO  c.g.C.c.async.AsyncTaskServiceDemo - Task-10 started.
14:00:38.430 [CP Thread-10] INFO  c.g.C.c.async.AsyncTaskServiceDemo - Task-9 started.
14:00:38.422 [CP Thread-1] INFO  c.g.C.c.async.AsyncTaskServiceDemo - Task-0 started.
14:00:38.430 [CP Thread-9] INFO  c.g.C.c.async.AsyncTaskServiceDemo - Task-8 started.
14:00:38.430 [CP Thread-8] INFO  c.g.C.c.async.AsyncTaskServiceDemo - Task-7 started.
14:00:38.430 [CP Thread-7] INFO  c.g.C.c.async.AsyncTaskServiceDemo - Task-6 started.
14:00:38.431 [CP Thread-10] INFO  c.g.C.c.async.AsyncTaskServiceDemo - i 9 sleep start...
14:00:38.430 [CP Thread-5] INFO  c.g.C.c.async.AsyncTaskServiceDemo - Task-4 started.
14:00:38.429 [CP Thread-4] INFO  c.g.C.c.async.AsyncTaskServiceDemo - Task-3 started.
14:00:38.435 [CP Thread-4] INFO  c.g.C.c.async.AsyncTaskServiceDemo - i 3 sleep start...
14:00:38.429 [CP Thread-3] INFO  c.g.C.c.async.AsyncTaskServiceDemo - Task-2 started.
14:00:38.429 [CP Thread-2] INFO  c.g.C.c.async.AsyncTaskServiceDemo - Task-1 started.
14:00:38.429 [CP Thread-20] INFO  c.g.C.c.async.AsyncTaskServiceDemo - Task-19 started.
14:00:38.424 [CP Thread-19] INFO  c.g.C.c.async.AsyncTaskServiceDemo - Task-18 started.
14:00:38.424 [CP Thread-18] INFO  c.g.C.c.async.AsyncTaskServiceDemo - Task-17 started.
14:00:38.437 [CP Thread-19] INFO  c.g.C.c.async.AsyncTaskServiceDemo - i 18 sleep start...
14:00:38.423 [CP Thread-13] INFO  c.g.C.c.async.AsyncTaskServiceDemo - Task-12 started.
14:00:38.438 [CP Thread-13] INFO  c.g.C.c.async.AsyncTaskServiceDemo - i 12 sleep start...
14:00:38.424 [CP Thread-17] INFO  c.g.C.c.async.AsyncTaskServiceDemo - Task-16 started.
14:00:38.424 [CP Thread-16] INFO  c.g.C.c.async.AsyncTaskServiceDemo - Task-15 started.
14:00:38.439 [CP Thread-16] INFO  c.g.C.c.async.AsyncTaskServiceDemo - i 15 sleep start...
14:00:38.424 [CP Thread-15] INFO  c.g.C.c.async.AsyncTaskServiceDemo - Task-14 started.
14:00:38.423 [CP Thread-14] INFO  c.g.C.c.async.AsyncTaskServiceDemo - Task-13 started.
14:00:38.434 [CP Thread-1] INFO  c.g.C.c.async.AsyncTaskServiceDemo - i 0 sleep start...
14:00:38.434 [CP Thread-7] INFO  c.g.C.c.async.AsyncTaskServiceDemo - i 6 sleep start...
14:00:38.423 [CP Thread-12] INFO  c.g.C.c.async.AsyncTaskServiceDemo - Task-11 started.
14:00:38.430 [CP Thread-6] INFO  c.g.C.c.async.AsyncTaskServiceDemo - Task-5 started.
14:00:39.033 [CP Thread-16] INFO  c.g.C.c.async.AsyncTaskServiceDemo - i 15 sleep end...
14:00:39.033 [CP Thread-13] INFO  c.g.C.c.async.AsyncTaskServiceDemo - i 12 sleep end...
14:00:39.033 [CP Thread-19] INFO  c.g.C.c.async.AsyncTaskServiceDemo - i 18 sleep end...
14:00:39.034 [CP Thread-7] INFO  c.g.C.c.async.AsyncTaskServiceDemo - i 6 sleep end...
14:00:39.034 [CP Thread-4] INFO  c.g.C.c.async.AsyncTaskServiceDemo - i 3 sleep end...
14:00:39.034 [CP Thread-10] INFO  c.g.C.c.async.AsyncTaskServiceDemo - i 9 sleep end...
14:00:39.034 [CP Thread-1] INFO  c.g.C.c.async.AsyncTaskServiceDemo - i 0 sleep end...

通过日志可以明显看出每一次调用异步处理方法doTask时都是获取了不同的线程,如CP Thread-19。并且是异步执行的。

ok

demo如此简单,具体业务逻辑可以在这个基础之上起飞了。祝,同行们,Happy everyday!

 

 

springboot使用线程池的实际应用(一) 具体来说,假设我们有10个用户同时调用了这个方法,那么这个方法会被执行10次,但是这10个用户会共用一个线程池中的线程去执行查询操作,而且查询操作是异步执行的,所以并不会阻塞当前线程。在这个过程中,如果线程池中的线程数量还没有达到10个,那么这个30个查询操作中的前10个会被分配到10个线程中执行,剩下的20个查询操作会被存储在工作队列中。其实正确的表述应该是“查询结果中的30个用户数据会被放入工作队列中等待处理”,也就是说,我们将查询操作获取到的结果数据放入一个队列中,然后使用线程池来处理这些数据。 阅读详情

相关推荐

日志异常检测详细整理,看这一篇就够了(附各项目代码链接)

对于不用的日志键,用它们的参数值向量训练一个参数值异常检测模型来检测有这些参数值反映的系统性能异常。与标准的GAN框架一样,D和G的参数是基于D的输出来更新的,因此鉴别器D可以被训练为尽可能敏感地将正确的标签分配给真实和虚假序列,而生成器将被训练为尽可能聪明地在经过足够多轮的迭代后欺骗鉴别器,即误导D将真实标签分配给虚假序列。LR:逻辑回归是有监督的模型,将处理后的特征矩阵以及标记作为模型的输入,得到训练后的模型,用此模型预测新出现的特征向量,以此判断特征向量是否为异常的,进而判断日志异常。

qq_20368489的博客 1万+

Springboot自带线程池

骑着蜗牛去旅游

weixin_45874214的博客 7249

从放弃到再入门之拉格朗日对偶问题推导

普通同学的解法 无约束条件:求导就可以了 等式约束:代入消元,再求导 不等式约束:分情况讨论(在边界上和不在边界上),分别对应1,2的情况 然而发现,有些情况消元特别复杂,甚至不能求解 聪明同学的解法 发现:在最优点的情况下,约束曲面的法向量和目标函数的梯度反向必相同或相反 拉格朗日乘子法如何理解? (在2维里可以形象的解释为z=f(x,y)在约束条件g(x,y)=c中,极值...

qq_34564612的博客 1万+

java解决包依赖冲突

后端报错如下: WARN [] o.s.b.t.j.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer.logDuplicateJsonObjectsWarning - Found multiple occurrences of org.json.JSONObject on the class path: jar:file:/D:/java_code/maven/repository/or

LOVEYSUXIN的专栏 2442

TypeScript版LangChain环境配置全攻略:从零搭建AI应用开发环境

大语言模型(LLM)作为当前AI应用开发的核心技术,通过API接口为开发者提供了强大的自然语言处理能力。其工作原理基于Transformer架构,通过预训练和微调实现对人类语言的深度理解与生成。在工程实践中,开发者需要将LLM与外部工具、数据源和业务逻辑有效集成,这正是LangChain框架的技术价值所在——它提供了标准化的组件和接口,简化了复杂AI应用的构建流程。应用场景涵盖智能客服、内容生成、数据分析助手等多个领域。本文聚焦于TypeScript/JavaScript生态下的LangChain开发,详细

weixin_29055699的博客 253

零代码做游戏:AI辅助开发HTML5网页小游戏从创意到发布全流程

在软件开发领域,自然语言编程正成为一种新兴的人机协作方式,而AI辅助开发则是其最典型的落地形态。它让开发者无需精通语法,只需用清晰的语言描述游戏规则与交互逻辑,AI便能自动生成可运行的代码。这种模式大幅降低了编程门槛,尤其适合快速验证创意、制作原型。对于HTML5网页游戏而言,借助AI生成单个HTML文件,配合在线运行环境,即可在浏览器中直接试玩、迭代与分享。无论是产品经理验证玩法、运营人员制作互动小游戏,还是教育者设计课堂闯关,都能通过自然语言描述需求,让AI完成代码实现与报错修复。本文完整记录了一个“接

weixin_31497453的博客 331

SpringBoot中的线程池

前两天做项目的时候,想提高一下插入表的性能优化,因为是两张表,先插旧的表,紧接着插新的表,一万多条数据就有点慢了后面就想到了线程池ThreadPoolExecutor,而用的是Spring Boot项目,可以用Spring提供的对ThreadPoolExecutor封装的线程池ThreadPoolTaskExecutor,直接使用注解启用。

z_ssyy的博客 2296

告别黑窗口:XShell+X11转发图形化界面的5分钟保姆级教程(附Xming配置)

本文详细介绍了如何使用XShell和X11转发技术快速实现Linux图形化界面的远程访问。通过5分钟快速配置指南,包括服务端设置、客户端工具选择及XShell+Xming的完美配置,帮助用户高效运行GUI应用程序,提升远程工作效率。特别适合需要图形化操作的开发者和运维人员。

weixin_29223603的博客 328

SpringBoot 异步使用@Async原理及线程池配置

所谓异步任务,其实就是异步执行程序,有些时候遇到一些耗时的的任务,如果一直卡等待,肯定会影响其他程序的执行,所以就让这些程序需要以异步的方式去执行。那么下面就来介绍Spring Boot 如何实现异步任务。 Spring中用@Async注解标记的方法,称为异步方法。在spring boot应用中使用@Async很简单: 调用异步方法类上或者启动类加上注解@EnableAsync 在需要被异步调用的方法外加上@Async 所使用的@Async注解方法的类对象应该是Spring容器管理的bean对象 注解配

魂-淡 8576

Cloudflare 5秒盾逆向实战:13次请求背后的Python补环境框架搭建指南

本文深入解析了如何通过Python构建浏览器环境模拟框架,以应对Cloudflare 5秒盾等现代Web防护机制。文章详细拆解了其背后复杂的13次请求链,涵盖了JavaScript执行引擎集成、DOM事件模拟、网络请求控制及Canvas指纹等环境检测的完整实现方案,为自动化数据采集和逆向工程提供了实战指南。

gold的博客 348

高速PCB设计中串扰的成因、影响与实战控制策略

在高速数字电路与硬件系统设计中,信号完整性是确保系统稳定可靠的核心基础。其核心原理在于,当信号在传输线上传播时,会伴随产生电场与磁场,若相邻导线距离过近,便会通过电磁场耦合产生不期望的能量转移,即串扰。这一现象会直接导致信号波形畸变、时序偏移和噪声裕量降低,严重影响系统性能。从技术价值看,深入理解并有效控制串扰,是提升数据传输速率、保障系统稳定性和降低误码率的关键。其应用场景广泛覆盖了从高速SerDes链路、DDR内存接口到高精度模拟电路等几乎所有现代电子系统。本文聚焦于高速PCB设计中的串扰问题,系统剖析

weixin_27625589的博客 576

求救!!!

java.lang.IllegalStateException: Failed to load ApplicationContext for [MergedContextConfiguration@5fb7183b testClass = demo.build.project.MerchantTest, locations = [], classes = [demo.build.project.ProjectApplication], contextInitializerClasses = [], acti

weixin_65778255的博客 434

NVIDIA Isaac Sim 入门教程 - 运动生成控制器(Motion Generators)

机器人任务通常在任务空间中根据所需的末端执行器轨迹进行定义,而控制动作则在关节空间中执行。这自然会产生关节空间和任务空间(操作空间)控制方法。然而,要利用运动控制成功执行交互任务,往往需要对机械臂及其环境都建立精确的模型。虽然可以知道足够精确的机械臂模型,但很难获得详细的环境描述 [SSVO09]。可以通过在交互过程中引入顺应行为来克服这种不匹配造成的规划错误。虽然顺应性可以通过机器人的结构(如弹性致动器、软机械臂)被动实现,但我们对侧重于主动交互控制的控制器设计更感兴趣。这些设计大致分为注释。

2506_90492529的博客 1578

Springboot项目中线程池使用整理

Spring环境:优先使用@Bean配置ThreadPoolTaskExecutor全局异步配置:实现AsyncConfigurer接口特殊性能要求:使用private static final方式。

2509_93961744的博客 280

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

【Java进阶】Java与SpringBoot线程池深度优化指南

java线程池与springboot线程池相关配置深度优化

wendao76的专栏 1033

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

上一篇: springboot slf4j配置日志输出到tomcat logs目录下
下一篇: window导入导出oracle数据库dmp备份文件命令行及常用命令和sql
grootblockchain
博客等级 码龄11年 55粉丝 101原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值