欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Spring Boot 多线程;SpringBoot 如何使用多线程

程序员文章站 2022-05-01 13:01:41
...

一般用多线程来解决项目中性能的问题,当然是在cpu 资源足够的前提下。

如果需要在调用方法A 而方法A 必须要调用方法A1,A2,A3 假设方法A1,A2,A3 各耗时1秒。

void methodA(){
	methodA1();
	methodA2();
	methodA3();
}

单线程 ,此时调用方法A的流程流程大致是这样的 A1结束——》A2结束——》A3结束, 那么整个方法A 调用完成至少需要3秒。

多线程 ,此时方法A1,A2,A3 会同时运行不存在排队和等待的情况,性能会提高很多。

下面简单说一下Spring Boot 如何使用多线程

线程池配置

	@Bean("testExecutor")
	public Executor asyncExecutor() {
		
		ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        //线程池创建时候初始化的线程数 
        executor.setCorePoolSize(5);
        //线程池最大的线程数,只有在缓冲队列满了之后才会申请超过核心线程数的线程
        executor.setMaxPoolSize(10);
        //用来缓冲执行任务的队列
        executor.setQueueCapacity(300);
        //当超过了核心线程出之外的线程在空闲时间到达之后会被销毁
        executor.setKeepAliveSeconds(60);
        // 线程前缀
        executor.setThreadNamePrefix("test-Async-");
        
        executor.initialize();
        
		return executor;
	}

未使用多线程的service

@Service
public class AsyncTestService {
	 private static final Logger logger = LoggerFactory.getLogger(AsyncTestService.class);
	
	 public CompletableFuture<String> taskOne(String requestId) throws InterruptedException{
		 Thread.sleep(1000L);
		 logger.info("request id : {} call task one",requestId);
		return CompletableFuture.completedFuture("Done");
		 
	 }
	 
	
	 public CompletableFuture<String> taskSecond(String requestId) throws InterruptedException{
		 Thread.sleep(1000L);
		 logger.info("request id : {} call task second",requestId);
		return CompletableFuture.completedFuture("Done");
		 
	 }
}

测试类

	@Test
	public void taskOneTest() throws InterruptedException, ExecutionException {
		long start = System.currentTimeMillis();
		CompletableFuture<String> task1_1 = asyncTestService.taskOne("1");
		CompletableFuture<String> task1_2 = asyncTestService.taskOne("2");
		CompletableFuture<String> task2_1 = asyncTestService.taskSecond("1");
		CompletableFuture<String> task2_2 = asyncTestService.taskSecond("2");
		// 待所有线程运行结束后再计算总耗时
		CompletableFuture.allOf(task1_1,task1_2,task2_1,task2_2).join();
		long end = System.currentTimeMillis();
		long elapsedTime = end - start;
		
		logger.info("elapsed time :{}",elapsedTime);
	}

总耗时为4秒多,中规中矩
Spring Boot 多线程;SpringBoot 如何使用多线程
在service 中的方法加上多线程注解 @Async(“XXX”) , XXX 即为bean name

	 @Async("testExecutor")
	 public CompletableFuture<String> taskOne(String requestId) throws InterruptedException{
		 Thread.sleep(1000L);
		 logger.info("request id : {} call task one",requestId);
		return CompletableFuture.completedFuture("Done");
		 
	 }
	 
	 @Async("testExecutor")
	 public CompletableFuture<String> taskSecond(String requestId) throws InterruptedException{
		 Thread.sleep(1000L);
		 logger.info("request id : {} call task second",requestId);
		return CompletableFuture.completedFuture("Done");
		 
	 }

总耗时为1秒多,性能以倍数提升。
Spring Boot 多线程;SpringBoot 如何使用多线程

总而言之,在cpu 资源许可的前提下使用多线程的效率会高一些。本文只是粗略说明如何在spring boot 中使用多线程,希望对大家有所帮助。当然关于如何规范合理地使用线程资源以及用多线程来处理业务逻辑的一些策略,这些问题还是值得大家去思考的。

共同学习,共同进步 Best Regard!