【SpringBoot】SpringBoot中使用线程池@EnableAsync

涉及到多线程的使用,总会绕不开一个概念——线程池,关于线程的原理及原始代码实现,这里不讲,网上有很多相关的博客,这里直接来介绍一下在SpringBoot中使用线程池来进行多线程的管理。

1、核心参数介绍
1、CorePoolSize:核心线程数,核心线程会一直存活,即使没有任务需要执行
2、MaxPoolSize:线程池中的最大线程数
3、QueueCapacity:阻塞队列的容量,用来存储等待执行的任务
4、KeepAliveSeconds:线程空闲时间
	//当线程空闲时间达到keepAliveTime时,线程会退出,直到线程数量=corePoolSize
	//如果allowCoreThreadTimeout=true,则会直到线程数量=0
5、RejectedExecutionHandler:拒绝策略
	// 当线程数达到MaxPoolSize时,且队列也慢,则会启用拒绝策略,拒绝的方式有五种:
	/*
	AbortPolicy 丢弃任务,抛运行时异常(默认的方式)
	CallerRunsPolicy 执行任务
	DiscardPolicy 忽视,什么都不会发生(常用方式)
	DiscardOldestPolicy 从队列中踢出最先进入队列(最后一个执行)的任务
	实现RejectedExecutionHandler接口,可自定义处理器
	*/
2、线程池的执行过程

内容来源于博文Java线程池的使用
线程池的处理过程
1、判断核心线程池是否已满,如果不是,则创建线程执行任务
2、如果核心线程池满了,判断队列是否满了,如果队列没满,将任务放在队列中
3、如果队列满了,则判断线程池是否已满,如果没满,创建线程执行任务
4、如果线程池也满了,则按照拒绝策略对任务进行处理

3、简单的实现

在SpringBoot中使用注解的方式来生成线程池,从而实现线程的管理,在SpringBoot中使用线程池只需配置一个java.util.concurrent.Executor的Bean,线程池配置类如下:

@Configuration
@EnableAsync  // 开启多线程
public class ExecutorConfig {

	@Bean
	public Executor createExecutor() {
		ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
		executor.setCorePoolSize(2); // 设置线程池初始化线程数量
		executor.setMaxPoolSize(5); // 设置线程池最大线程数量
		executor.setQueueCapacity(10);// 设置缓冲队列的大小
		executor.setKeepAliveSeconds(200);// 线程的允许空闲时间(单位:s)
		executor.setThreadNamePrefix("Async-Service-"); // 线程名称前缀
		executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy()); // 设置线程拒绝策略
		executor.initialize();
		return executor;
	}
}

然后是使用:

@Component
public class SubThreads {
	Logger log = LoggerFactory.getLogger(SubThreads.class);

	@PostConstruct // 加上该注解项目启动时就执行一次该方法
	@Async
	public void sendMessage1() throws InterruptedException {
		log.info("发送短信方法---- 1   执行开始");
		Thread.sleep(5000);
		log.info("发送短信方法---- 1   执行结束");
	}

	@PostConstruct // 加上该注解项目启动时就执行一次该方法
	@Async
	public void sendMessage2() throws InterruptedException {

		log.info("发送短信方法---- 2   执行开始");
		Thread.sleep(2000);
		log.info("发送短信方法---- 2   执行结束");
	}

}

测试程序:

@RestController
public class TestController {
	@Autowired
	private SubThreads subThreads;

	@RequestMapping("/thread")
	public void testThread() throws InterruptedException {
		subThreads.sendMessage1();
		subThreads.sendMessage2();
	}
}

最后启动服务,在浏览器中访问,查看输出日志:


  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.2.2.RELEASE)

2019-12-16 13:29:56.398  INFO 20464 --- [  restartedMain] com.learn.Application                    : Starting Application on CNBJDRCNB019 with PID 20464 (D:\SDK\workspaces\cradle\learn-springboot-threadpool\target\classes started by Yinghao.Chen in D:\SDK\workspaces\cradle\learn-springboot-threadpool)
2019-12-16 13:29:56.402  INFO 20464 --- [  restartedMain] com.learn.Application                    : No active profile set, falling back to default profiles: default
2019-12-16 13:29:56.479  INFO 20464 --- [  restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : Devtools property defaults active! Set 'spring.devtools.add-properties' to 'false' to disable
2019-12-16 13:29:56.481  INFO 20464 --- [  restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : For additional web related logging consider setting the 'logging.level.web' property to 'DEBUG'
2019-12-16 13:29:57.913  INFO 20464 --- [  restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8885 (http)
2019-12-16 13:29:57.927  INFO 20464 --- [  restartedMain] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2019-12-16 13:29:57.927  INFO 20464 --- [  restartedMain] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.29]
2019-12-16 13:29:58.165  INFO 20464 --- [  restartedMain] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2019-12-16 13:29:58.165  INFO 20464 --- [  restartedMain] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1683 ms
2019-12-16 13:29:58.236  INFO 20464 --- [  restartedMain] com.learn.subthreads.SubThreads          : 发送短信方法---- 1   执行开始
2019-12-16 13:30:03.237  INFO 20464 --- [  restartedMain] com.learn.subthreads.SubThreads          : 发送短信方法---- 1   执行结束
2019-12-16 13:30:03.237  INFO 20464 --- [  restartedMain] com.learn.subthreads.SubThreads          : 发送短信方法---- 2   执行开始
2019-12-16 13:30:05.238  INFO 20464 --- [  restartedMain] com.learn.subthreads.SubThreads          : 发送短信方法---- 2   执行结束
2019-12-16 13:30:05.270  INFO 20464 --- [  restartedMain] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService
2019-12-16 13:30:05.272  INFO 20464 --- [  restartedMain] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'createExecutor'
2019-12-16 13:30:05.691  INFO 20464 --- [  restartedMain] o.s.b.d.a.OptionalLiveReloadServer       : LiveReload server is running on port 35729
2019-12-16 13:30:05.776  INFO 20464 --- [  restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8885 (http) with context path ''
2019-12-16 13:30:05.781  INFO 20464 --- [  restartedMain] com.learn.Application                    : Started Application in 9.94 seconds (JVM running for 12.883)
2019-12-16 13:30:35.810  INFO 20464 --- [nio-8885-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2019-12-16 13:30:35.810  INFO 20464 --- [nio-8885-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2019-12-16 13:30:35.819  INFO 20464 --- [nio-8885-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 9 ms
2019-12-16 13:30:35.874  INFO 20464 --- [Async-Service-1] com.learn.subthreads.SubThreads          : 发送短信方法---- 1   执行开始
2019-12-16 13:30:35.874  INFO 20464 --- [Async-Service-2] com.learn.subthreads.SubThreads          : 发送短信方法---- 2   执行开始
2019-12-16 13:30:37.876  INFO 20464 --- [Async-Service-2] com.learn.subthreads.SubThreads          : 发送短信方法---- 2   执行结束
2019-12-16 13:30:40.875  INFO 20464 --- [Async-Service-1] com.learn.subthreads.SubThreads          : 发送短信方法---- 1   执行结束

通过线程名字可以看出,配置的线程池已经起了作用。

发布了66 篇原创文章 · 获赞 6 · 访问量 9410

猜你喜欢

转载自blog.csdn.net/qgnczmnmn/article/details/103558489