spring-boot 方法异步调用,自定义线程池配置使用
2017-04-07 00:00
1136 查看
1、在主类中添加@EnableAsync注解:
2、创建一个AsyncTask类,在里面添加两个用@Async注解的task:
3、万事俱备,开始测试:
测试结果:
可以看到,没有自定义的Executor,所以使用缺省的TaskExecutor 。
前面是最简单的使用方法。如果想使用自定义的Executor,可以按照如下几步来:
1、新建一个Executor配置类,顺便把@EnableAsync注解搬到这里来:
这里定义了两个不同的Executor,第二个重新设置了pool已经达到max size时候的处理方法;同时指定了线程名字的前缀。
2、自定义Executor的使用:
就是把上面自定义Executor的类名,放进@Async注解中。
3、(测试用例不变)测试结果:
可见,线程名字的前缀变了,两个task使用了不同的线程池了。
参考博客:http://blog.csdn.net/clementad/article/details/53607311
@SpringBootApplication @EnableScheduling @EnableAsync public class MySpringBootApplication { private static Logger logger = LoggerFactory.getLogger(MySpringBootApplication.class); public static void main(String[] args) { SpringApplication.run(MySpringBootApplication.class, args); logger.info("My Spring Boot Application Started"); }
2、创建一个AsyncTask类,在里面添加两个用@Async注解的task:
@Component public class AsyncTask { protected final Logger logger = LoggerFactory.getLogger(this.getClass()); @Async public Future<String> doTask1() throws InterruptedException{ logger.info("Task1 started."); long start = System.currentTimeMillis(); Thread.sleep(5000); long end = System.currentTimeMillis(); logger.info("Task1 finished, time elapsed: {} ms.", end-start); return new AsyncResult<>("Task1 accomplished!"); } @Async public Future<String> doTask2() throws InterruptedException{ logger.info("Task2 started."); long start = System.currentTimeMillis(); Thread.sleep(3000); long end = System.currentTimeMillis(); logger.info("Task2 finished, time elapsed: {} ms.", end-start); return new AsyncResult<>("Task2 accomplished!"); } }
3、万事俱备,开始测试:
public class TaskTests extends BasicUtClass{ @Autowired private AsyncTask asyncTask; @Test public void AsyncTaskTest() throws InterruptedException, ExecutionException { Future<String> task1 = asyncTask.doTask1(); Future<String> task2 = asyncTask.doTask2(); while(true) { if(task1.isDone() && task2.isDone()) { logger.info("Task1 result: {}", task1.get()); logger.info("Task2 result: {}", task2.get()); break; } Thread.sleep(1000); } logger.info("All tasks finished."); } }
测试结果:
2016-12-13 11:12:24,850:INFO main (AsyncExecutionAspectSupport.java:245) - No TaskExecutor bean found for async processing 2016-12-13 11:12:24,864:INFO SimpleAsyncTaskExecutor-1 (AsyncTask.java:22) - Task1 started. 2016-12-13 11:12:24,865:INFO SimpleAsyncTaskExecutor-2 (AsyncTask.java:34) - Task2 started. 2016-12-13 11:12:27,869:INFO SimpleAsyncTaskExecutor-2 (AsyncTask.java:39) - Task2 finished, time elapsed: 3001 ms. 2016-12-13 11:12:29,866:INFO SimpleAsyncTaskExecutor-1 (AsyncTask.java:27) - Task1 finished, time elapsed: 5001 ms. 2016-12-13 11:12:30,853:INFO main (TaskTests.java:23) - Task1 result: Task1 accomplished! 2016-12-13 11:12:30,853:INFO main (TaskTests.java:24) - Task2 result: Task2 accomplished! 2016-12-13 11:12:30,854:INFO main (TaskTests.java:30) - All tasks finished.
可以看到,没有自定义的Executor,所以使用缺省的TaskExecutor 。
前面是最简单的使用方法。如果想使用自定义的Executor,可以按照如下几步来:
1、新建一个Executor配置类,顺便把@EnableAsync注解搬到这里来:
@Configuration @EnableAsync public class ExecutorConfig { /** Set the ThreadPoolExecutor's core pool size. */ private int corePoolSize = 10; /** Set the ThreadPoolExecutor's maximum pool size. */ private int maxPoolSize = 200; /** Set the capacity for the ThreadPoolExecutor's BlockingQueue. */ private int queueCapacity = 10; @Bean public Executor mySimpleAsync() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(corePoolSize); executor.setMaxPoolSize(maxPoolSize); executor.setQueueCapacity(queueCapacity); executor.setThreadNamePrefix("MySimpleExecutor-"); executor.initialize(); return executor; } @Bean public Executor myAsync() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(corePoolSize); executor.setMaxPoolSize(maxPoolSize); executor.setQueueCapacity(queueCapacity); executor.setThreadNamePrefix("MyExecutor-"); // rejection-policy:当pool已经达到max size的时候,如何处理新任务 // CALLER_RUNS:不在新线程中执行任务,而是有调用者所在的线程来执行 executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); executor.initialize(); return executor; } }
这里定义了两个不同的Executor,第二个重新设置了pool已经达到max size时候的处理方法;同时指定了线程名字的前缀。
2、自定义Executor的使用:
@Component public class AsyncTask { protected final Logger logger = LoggerFactory.getLogger(this.getClass()); @Async("mySimpleAsync") public Future<String> doTask1() throws InterruptedException{ logger.info("Task1 started."); long start = System.currentTimeMillis(); Thread.sleep(5000); long end = System.currentTimeMillis(); logger.info("Task1 finished, time elapsed: {} ms.", end-start); return new AsyncResult<>("Task1 accomplished!"); } @Async("myAsync") public Future<String> doTask2() throws InterruptedException{ logger.info("Task2 started."); long start = System.currentTimeMillis(); Thread.sleep(3000); long end = System.currentTimeMillis(); logger.info("Task2 finished, time elapsed: {} ms.", end-start); return new AsyncResult<>("Task2 accomplished!"); } }
就是把上面自定义Executor的类名,放进@Async注解中。
3、(测试用例不变)测试结果:
2016-12-13 10:57:11,998:INFO MySimpleExecutor-1 (AsyncTask.java:22) - Task1 started. 2016-12-13 10:57:12,001:INFO MyExecutor-1 (AsyncTask.java:34) - Task2 started. 2016-12-13 10:57:15,007:INFO MyExecutor-1 (AsyncTask.java:39) - Task2 finished, time elapsed: 3000 ms. 2016-12-13 10:57:16,999:INFO MySimpleExecutor-1 (AsyncTask.java:27) - Task1 finished, time elapsed: 5001 ms. 2016-12-13 10:57:17,994:INFO main (TaskTests.java:23) - Task1 result: Task1 accomplished! 2016-12-13 10:57:17,994:INFO main (TaskTests.java:24) - Task2 result: Task2 accomplished! 2016-12-13 10:57:17,994:INFO main (TaskTests.java:30) - All tasks finished. 2016-12-13 10:57:18,064 Thread-3 WARN Unable to register Log4j shutdown hook because JVM is shutting down. Using SimpleLogger
可见,线程名字的前缀变了,两个task使用了不同的线程池了。
参考博客:http://blog.csdn.net/clementad/article/details/53607311
相关文章推荐
- spring-boot 线程池 @Async 的使用、自定义Executor的配置方法
- spring boot使用自定义配置的线程池执行Async异步任务
- Spring Boot使用@Async实现异步调用:自定义线程池
- Spring Boot使用@Async实现异步调用:自定义线程池
- spring boot使用自定义配置的线程池执行Async异步任务
- springboot中使用定时任务,异步调用,自定义配置参数(八)
- spring boot 使用@Async实现异步调用方法
- spring-boot @Async 的使用、自定义Executor的配置方法
- springBoot使用Controller读取配置文件两种方式&读取自定义配置方法
- Spring Boot利用@Async如何实现异步调用:自定义线程池
- spring-boot @Async 的使用、自定义Executor的配置方法
- spring-boot 自定义Executor的配置方法及@Async的使用
- spring-boot @Async 的使用、自定义Executor的配置方法
- SpringBoot--@Async 的使用、自定义Executor的配置方法
- spring-boot @Async 的使用、自定义Executor的配置方法
- spring-boot实战【10】【转】:Spring Boot中使用@Async实现异步调用
- spring boot 多线程,异步方法和异步类的注解使用
- SpringBoot配置自定义线程池的数据源
- 基于Spring Boot不同的环境使用不同的配置方法
- spring boot使用自定义的线程池执行Async任务