Spring boot使用多线程过程步骤解析

2025-05-29 0 47

Spring中实现多线程,其实非常简单,只需要在配置类中添加@EnableAsync就可以使用多线程。在希望执行的并发方法中使用@Async就可以定义一个线程任务。通过spring给我们提供的ThreadPoolTaskExecutor就可以使用线程池。

第一步,先在Spring Boot主类中定义一个线程池,比如:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31
package com.jmxf.core.config;

import java.util.concurrent.Executor;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.scheduling.annotation.EnableAsync;

import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

@Configuration

@EnableAsync // 启用异步任务

public class AsyncConfiguration {

// 组件计算

@Bean("zjExecutor")

public Executor asyncExecutor() {

ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();

//核心线程数5:线程池创建时候初始化的线程数

executor.setCorePoolSize(5);

//最大线程数5:线程池最大的线程数,只有在缓冲队列满了之后才会申请超过核心线程数的线程

executor.setMaxPoolSize(10);

//缓冲队列500:用来缓冲执行任务的队列

executor.setQueueCapacity(500);

//允许线程的空闲时间60秒:当超过了核心线程出之外的线程在空闲时间到达之后会被销毁

executor.setKeepAliveSeconds(60);

//线程池名的前缀:设置好了之后可以方便我们定位处理任务所在的线程池

executor.setThreadNamePrefix("DailyAsync-");

executor.initialize();

return executor;

}

}

有很多你可以配置的东西。默认情况下,使用SimpleAsyncTaskExecutor。

第二步,使用线程池

在定义了线程池之后,我们如何让异步调用的执行任务使用这个线程池中的资源来运行呢?方法非常简单,我们只需要在@Async注解中指定线程池名即可,比如:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33
package com.jmxf.service.fkqManage.zj;

import org.springframework.scheduling.annotation.Async;

@Service

public class CentreZj {

/**

* 多线程执行 zj计算推数

* @param fkqZj

* @throws Exception

*/

@Async("zjExecutor")

public CompletableFuture<String> executeZj (FkqZj fkqZj) {

if(fkqZj == null) return;

String zjid = fkqZj.getZjid();

FkqHdzjdm zjdm = getZjdm(zjid);

String zjlj = zjdm.getZjlj();

if(StringUtils.isBlank(zjlj)) return;

Object bean = ApplicationContextProvider.getBean(zjlj);

Method method;

try {

method = bean.getClass().getMethod("refresh",String.class);

method.invoke(bean,zjid);

} catch (Exception e) {

e.printStackTrace();

}

}

return CompletableFuture.completedFuture(zjid);

}

executeZj方法被标记为Spring的 @Async 注解,表示它将在一个单独的线程上运行。该方法的返回类型是 CompleetableFuture 而不是 String,这是任何异步服务的要求。

第三步,调用测试

?

1

2

3

4

5

6

7

8

9
List<CompletableFuture<String>> executeZjs = new ArrayList<>();

for (FkqZj fkqZj : zjs) {

CompletableFuture<String> executeZj = centreZj.executeZj(fkqZj);

executeZjs.add(executeZj);

}

//等待所以子线程结束后 返回结果

for (CompletableFuture<String> completableFuture : executeZjs) {

CompletableFuture.allOf(completableFuture).join();

}

注意事项

异步方法和调用方法一定要写在不同的类中 ,如果写在一个类中,是没有效果的!

原因:

spring对@Transactional注解时也有类似问题,spring扫描时具有@Transactional注解方法的类时,是生成一个代理类,由代理类去开启关闭事务,而在同一个类中,方法调用是在类体内执行的,spring无法截获这个方法调用。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持快网idc。

原文链接:https://www.cnblogs.com/MisMe/p/13390092.html

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 建站教程 Spring boot使用多线程过程步骤解析 https://www.kuaiidc.com/119002.html

相关文章

发表评论
暂无评论