@Async源碼探究

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());
    }

}

結果spring

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源碼找到以下信息,爲它默認線程池設置屬性
    app

  • 咱們把運行數量加大到count=20
  • 結果async

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給你建立了線程池了
相關文章
相關標籤/搜索