SpringBoot实践之---@EnableAsync和@Async 线程池自定义和使用

    自定义线程池的配置类  AsyncConfig

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.TaskExecutor;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.ThreadPoolExecutor;

@Configuration
@EnableAsync
/** 
* @Description: 自定义线程池的配置类,并在类上添加@EnableAsync 注解,
 * 然后在需要异步的方法上使用@Async("线程池名称") 该方法就可以异步执行了
* @Param:  * @param null 
* @return:  
* @Author: wenliang 
* @Date: 2019/11/6 
**/ 
public class AsyncConfig {
	private static final Logger logger = LoggerFactory.getLogger(AsyncConfig.class);
	@Bean("taskExecutor") // bean的名称,,不写的里面值,则默认为首字母小写的方法名
	public TaskExecutor taskExecutor() {
		logger.info("start asyncServiceExecutor");
		ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
		int core = Runtime.getRuntime().availableProcessors();
		//配置核心线程数
		executor.setCorePoolSize(core);
		//配置最大线程数
		executor.setMaxPoolSize(core * 2 + 1);
		// 允许线程空闲时间(单位:默认为秒)
		executor.setKeepAliveSeconds(5);
		//配置队列大小
		executor.setQueueCapacity(9999);
		//配置线程池中的线程的名称前缀
		executor.setThreadNamePrefix("async-service-");

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

}

注① @Configuration用于定义配置类,可替换xml配置文件,被注解的类内部包含有一个或多个被@Bean注解的方法,这些方法将会被AnnotationConfigApplicationContext或AnnotationConfigWebApplicationContext类进行扫描,并用于构建bean定义,初始化Spring容器。

注② @EnableAsync开始对异步任务的支持

接着写个service类 testAsyncService :
 

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
 
@Service
public class testAsyncService {
	Logger log = LoggerFactory.getLogger(testAsyncService.class);
 
	// 发送提醒短信 1
	@Async("taskExecutor")
	public void service1() throws InterruptedException {
		log.info("--------start-service1------------");
		Thread.sleep(5000); // 模拟耗时
	    log.info("--------end-service1------------");
	}
	
	// 发送提醒短信 2
	@Async("taskExecutor")
	public void service2() throws InterruptedException {
		
		log.info("--------start-service2------------");
		Thread.sleep(2000); // 模拟耗时
	    log.info("--------end-service2------------");
 
	}

注① 使用@Async注解来声明一个或多个异步任务,可以加在方法或者类上,加在类上表示这整个类都是使用这个自定义线程池进行操作

接着我们可以创建control类@Autowired这个service并且调用这其中两个方法,进行连续调用,会发现运行结果是

     --------start-service1------------

     --------start-service2------------

     --------end-service2------------

     --------end-service1------------

可以说明我们的异步运行成功了

注意点:

一、异步方法使用static修饰
二、异步类没有使用@Component注解(或其他注解)导致spring无法扫描到异步类
三、类中需要使用@Autowired或@Resource等注解自动注入,不能自己手动new对象
五、如果使用SpringBoot框架必须在启动类中增加@EnableAsync注解
 

在Spring Boot中,你可以通过两种方式来自定义线程池。 第一种方式是自定义线程池。你可以在`application.yml`配置文件中设置线程池的参数,如核心线程数、最大线程数、空闲线程存活时间、队列容量等。具体配置如下: ```yaml task: pool: corePoolSize: 10 maxPoolSize: 20 keepAliveTime: 300 queueCapacity: 100 threadNamePrefix: "-signpolicy-asynnotify-" awaitTerminationSeconds: 60 spring: main: allow-bean-definition-overriding: true ``` 同时,你需要创建一个线程池配置属性类,用于读取配置文件中的参数。具体代码如下: ```java package com.example.config; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; @Data @ConfigurationProperties(prefix = "task.pool") public class TaskThreadPoolConfig { private int corePoolSize; private int maxPoolSize; private int keepAliveSeconds; private int queueCapacity; private int awaitTerminationSeconds; private String threadNamePrefix; } ``` 第二种方式是重写Spring默认线程池。你只需要在需要执行异步任务的方法上添加`@Async`注解,不需要声明线程池类。具体代码如下: ```java import org.springframework.boot.context.properties.ConfigurationProperties; @ConfigurationProperties(prefix = "task.pool") public class TaskThreadPoolConfig { // 省略其他属性 } ``` 请注意,需要在启动类上添加`@EnableAsync`注解来开启异步线程支持。 这两种方式都可以实现自定义线程池的功能,你可以根据实际需求选择其中一种方式来使用。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [SpringBoot 自定义线程池](https://blog.csdn.net/web18334137065/article/details/126114296)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [springboot自定义线程池](https://blog.csdn.net/weixin_52774180/article/details/124673844)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值