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

网友投稿 1317 2023-05-06

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

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

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

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

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注解中指定线程池名即可,比如:

package com.jmxf.service.fkqManage.zhttp://j;

import org.springframework.scheduling.annotation.Async;

@Service

public class CentreZj {

/**

* 多线程执行 zj计算推数

* @param fkqZj

* @throws Exception

*/

@Async("zjExecutor")

public CompletableFuture 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,这是任何异步服务的要求。

第三步,调用测试

List> executeZjs = new ArrayList<>();

for (FkqZj fkqZj : zjs) {

CompletableFuture executeZhttp://j = centreZj.executeZj(fkqZj);

executeZjs.add(executeZj);

}

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

for (CompletableFuture<String> completableFuture : executeZjs) {

CompletableFuture.allOf(completableFuture).join();

}

注意事项

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

原因:

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

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Springboot项目因为kackson版本问题启动报错解决方案
下一篇:log4j2 自动删除过期日志文件的配置及实现原理
相关文章

 发表评论

暂时没有评论,来抢沙发吧~