@Async源码探究

做~自己de王妃 提交于 2019-11-30 18:54:48

1. @Async源码探究

1.1. 上代码

@SpringBootApplication @EnableAsync public class SpringbootLearnApplication {      public static void main(String[] args) {         SpringApplication.run(SpringbootLearnApplication.class, args);     }  }
@Service public class CreatingThread08Service {      @Async     public void call(CountDownLatch countDownLatch) {         try {             Thread.sleep(1000);         } catch (InterruptedException e) {             e.printStackTrace();         }         System.out.println(Thread.currentThread().getName() + " is running");         countDownLatch.countDown();         System.out.println(Thread.currentThread().getName() + " is over");      } } 
@RunWith(SpringRunner.class) @SpringBootTest public class SpringbootLearnApplicationTests {      @Autowired     private CreatingThread08Service creatingThread08Service;      private int count = 4;      private CountDownLatch countDownLatch = new CountDownLatch(count);      @Test     public void contextLoads() {          StopWatch stopwatch = new StopWatch("async test");         stopwatch.start();         for (int i = 0; i < count; i++) {             creatingThread08Service.call(countDownLatch);         }         try {             countDownLatch.await();         } catch (InterruptedException e) {             e.printStackTrace();         }         stopwatch.stop();         System.out.println(stopwatch.prettyPrint());     }  } 

结果

task-2 is running task-2 is over task-4 is running task-4 is over task-1 is running task-1 is over task-3 is running task-3 is over StopWatch 'async test': running time (millis) = 1018 ----------------------------------------- ms     %     Task name ----------------------------------------- 01018  100%   

1.2. 提问

1.2.1. 加了该注解的方法,如果同时被调用n次,难道会创建n个线程?

  • 通过debugger源码找到如下信息,为它默认线程池设置属性

  • 我们把运行数量加大到count=20
  • 结果

task-1 is running task-1 is over task-8 is running task-8 is over task-5 is running task-5 is over task-3 is running task-3 is over task-4 is running task-4 is over task-7 is running task-7 is over task-2 is running task-2 is over task-6 is running task-6 is over task-1 is running task-1 is over task-8 is running task-3 is running task-3 is over task-5 is running task-5 is over task-8 is over task-4 is running task-6 is running task-6 is over task-7 is running task-7 is over task-2 is running task-2 is over task-4 is over task-5 is running task-1 is running task-8 is running task-8 is over task-1 is over task-3 is running task-3 is over task-5 is over StopWatch 'async test': running time (millis) = 3021 ----------------------------------------- ms     %     Task name ----------------------------------------- 03021  100%  
  • 可以看出,如截图一致,它的运行核心执行线程数为8,且队列数很大,所以几乎不会再创建新的线程数,我特意sleep了1秒,20个任务,足够该线程池运行3遍,所以最大延迟3秒多

1.3. 那么核心线程数这个值能够变吗?

  • 可以,通过application.properties中修改spring.task.execution.pool.core-size=20的值,比如我现在改成20,那么打印结果如下
task-1 is running task-9 is running task-12 is running task-15 is running task-17 is running task-11 is running task-11 is over task-1 is over task-10 is running task-10 is over task-8 is running task-8 is over task-6 is running task-6 is over task-4 is running task-4 is over task-7 is running task-7 is over task-5 is running task-3 is running task-3 is over task-20 is running task-20 is over task-17 is over task-19 is running task-19 is over task-2 is running task-2 is over task-18 is running task-18 is over task-15 is over task-16 is running task-16 is over task-12 is over task-14 is running task-14 is over task-13 is running task-13 is over task-9 is over task-5 is over StopWatch 'async test': running time (millis) = 1020 ----------------------------------------- ms     %     Task name ----------------------------------------- 01020  100%  
  • 所有线程只执行一遍,最大延迟就1秒多了

1.4. 总结

  • 使用该注解,会创建默认核心线程为8的线程池,它的很多属性是可以通过配置设置的,如下
spring.task.execution.pool.core-size=10 spring.task.execution.thread-name-prefix=mytask- spring.task.execution.pool.queue-capacity=10 spring.task.execution.pool.max-size=20 spring.task.execution.pool.keep-alive=60s spring.task.execution.pool.allow-core-thread-timeout=true
  • 根据业务需求设置合理的属性值,就相当于spring给你创建了线程池了
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!