SpringBoot之使用自定义线程池实现异步任务

使用自定义线程池实现异步任务

配置自己的线程池

@Configuration
public class ThreadConfig {
	//核心线程池大小
	private final int poolSize = 10;
	//最大线程数
	private final int maxPoolSize = 18;
	//队列容量
	private final int queueCapacity = 30;
	//活跃时间/秒
	private final int keepAliveSeconds = 30;

	@Bean("myThreadPoll")
	public Executor myThreadPool() {
		ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
		executor.setCorePoolSize(poolSize);
		executor.setMaxPoolSize(maxPoolSize);
		executor.setQueueCapacity(queueCapacity);
		executor.setKeepAliveSeconds(keepAliveSeconds);
		executor.setThreadNamePrefix("myThread-zgl-");//前缀名
		//当池中的线程使用完时,新任务由调用者所在的线程执行
		executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
		executor.initialize();
		return  executor;
	}
}

service代码

@Service
public class TestThreadPoolService {
	@Async("myThreadPoll")
	public void hi(int num) throws InterruptedException {
		Thread.sleep(5000);
		System.out.println("任务"+num +"由"+Thread.currentThread().getName()+"执行完成!!");
	}
}

controller代码

@Controller
public class TestThreadPoolController {
	@Autowired TestThreadPoolService testThreadPoolService;

	@GetMapping("/hello2")
	public String test() throws InterruptedException, ExecutionException {
		long start = System.currentTimeMillis();

		for (int i = 0; i < 50; i++) {
			testThreadPoolService.hi(i);
		}
		System.out.println("耗时"+(System.currentTimeMillis() - start)+"毫秒" );
		return "index";
	}
}

运行代码结果:

任务5由myThread-zgl-6执行完成!!
任务47由myThread-zgl-18执行完成!!
任务42由myThread-zgl-13执行完成!!
任务9由myThread-zgl-10执行完成!!
任务48由http-nio-8081-exec-1执行完成!!
任务4由myThread-zgl-5执行完成!!
任务2由myThread-zgl-3执行完成!!
任务1由myThread-zgl-2执行完成!!
任务7由myThread-zgl-8执行完成!!
任务3由myThread-zgl-4执行完成!!
任务45由myThread-zgl-16执行完成!!
任务43由myThread-zgl-14执行完成!!
任务6由myThread-zgl-7执行完成!!
任务0由myThread-zgl-1执行完成!!
任务46由myThread-zgl-17执行完成!!
任务8由myThread-zgl-9执行完成!!
任务40由myThread-zgl-11执行完成!!
任务41由myThread-zgl-12执行完成!!
任务44由myThread-zgl-15执行完成!!
耗时5007毫秒
任务10由myThread-zgl-6执行完成!!
任务27由myThread-zgl-15执行完成!!
任务26由myThread-zgl-12执行完成!!
任务24由myThread-zgl-9执行完成!!
任务19由myThread-zgl-16执行完成!!
任务25由myThread-zgl-11执行完成!!
任务23由myThread-zgl-17执行完成!!
任务21由myThread-zgl-7执行完成!!
任务22由myThread-zgl-1执行完成!!
任务20由myThread-zgl-14执行完成!!
任务18由myThread-zgl-4执行完成!!
任务16由myThread-zgl-2执行完成!!
任务17由myThread-zgl-8执行完成!!
任务15由myThread-zgl-3执行完成!!
任务11由myThread-zgl-13执行完成!!
任务13由myThread-zgl-10执行完成!!
任务14由myThread-zgl-5执行完成!!
任务12由myThread-zgl-18执行完成!!
任务33由myThread-zgl-11执行完成!!
任务38由myThread-zgl-4执行完成!!
任务49由myThread-zgl-8执行完成!!
任务39由myThread-zgl-2执行完成!!
任务37由myThread-zgl-14执行完成!!
任务36由myThread-zgl-1执行完成!!
任务30由myThread-zgl-12执行完成!!
任务32由myThread-zgl-16执行完成!!
任务34由myThread-zgl-17执行完成!!
任务28由myThread-zgl-6执行完成!!
任务29由myThread-zgl-15执行完成!!
任务31由myThread-zgl-9执行完成!!
任务35由myThread-zgl-7执行完成!!

实现了自定义线程池来执行异步任务

### Spring Boot 自定义线程池配置与异步任务使用 #### 一、基本概念介绍 在Spring Boot中,`ThreadPoolTaskExecutor`被提供作为默认的线程池实现[^1]。为了更灵活地控制应用中的并发行为,可以创建并配置自己的线程池。 对于希望标记为异步执行的方法,则可以通过添加`@Async`注解来达成目的;需要注意的是,在项目启动类或任意配置类上需启用异步支持即加上`@EnableAsync`注解才能使此功能生效[^4]。 #### 二、自定义线程池配置方式 一种常见的做法是在应用程序内通过继承`AsyncConfigurer`接口来自定义线程池设置[^3]: ```java @Configuration @EnableAsync public class AsyncConfig implements AsyncConfigurer { @Override public Executor getAsyncExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); // 设置核心线程数 executor.setCorePoolSize(5); // 设置最大线程数 executor.setMaxPoolSize(10); // 设置队列容量 executor.setQueueCapacity(25); // 初始化线程池 executor.initialize(); return executor; } } ``` 上述代码片段展示了如何基于`ThreadPoolTaskExecutor`构建一个具有特定参数设定(比如核心/最大线程数量以及等待队列大小)的线程池实例,并将其注册到Spring容器以便后续调用。 #### 三、编写异步服务方法 一旦完成了线程池的基础搭建工作之后,便可以在业务逻辑层面上利用这些资源了。下面给出一段简单的例子说明怎样声明一个能够异步运行的服务函数[^2]: ```java @Service public class AsyncTaskService { @Async public void executeAsyncTask(Integer i) throws InterruptedException{ System.out.println( "Start async task at:" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) ); Thread.sleep(i * 1000L); // Simulate delay with sleep. System.out.println( "End async task at:" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) ); } } ``` 这里的关键在于给目标方法打上了`@Async`标签,这表明当有客户端请求触发这个操作时,它将会在线程池里新开辟出来的子进程中完成而不是阻塞住主线程继续往下走。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值