SpringBoot的線程調度


Spring Boot默認提供了一個ThreadPoolTaskExecutor作為線程調度器,只需要在配置類中使用注解EnableAsync即可開啟異步線程調度。在實際要執行的Bean中使用@Async注解來聲明這個方法是異步方法,需要通過線程調度器來執行。

示例代碼如下:

Application類,開啟異步線程調度

@SpringBootApplication
@EnableAsync
public class TestApplication {

	public static void main(String[] args) {
		SpringApplication.run(TestApplication.class, args);
	}
}

異步任務類,聲明execute()方法通過線程調度器執行

@Service
public class TestAsync {
  
  private static AtomicInteger count = new AtomicInteger(0);

  @Async
  public String execute() {
    System.out.println("begin execute TestAsync: " + count.incrementAndGet());
    try {
      Thread.sleep(10000);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
    System.out.println("finished execute TestAsync");
    return "result";
  }
}

要注意的問題:

(1)這里的@Async注解必須要聲明在Bean對外提供的方法上,如果這個方法不是由其它類直接調用,而是這個類的其它方法間接調用,則不生效。
(2)@Async注解聲明的方法,返回類型要么聲明為void,要么聲明為Future。因為方法是異步調用,因此無法立即返回結果,如果聲明為其它返回類型,則獲取到的是null。聲明為Future,則可以獲取到任務的執行結果。

Controller類

@RestController
public class TestAsyncController {
  
  @Autowired
  private TestAsync testAsync;
  
  @RequestMapping(value = "/async", method = RequestMethod.GET)
  public String async() {
    System.out.println("before execute TestAsync");
    String result =  testAsync.outexecute();
    System.out.println("after execute TestAsync");
    return result;
  }
}

這里獲取到的result值null,因此獲取這個返回值沒有什么意義。

Spring Boot線程調度有以下幾個參數可以配置(2.1版本之后才有):
spring.task.execution.pool.core-size # 核心線程數,默認為8
spring.task.execution.pool.queue-capacity # 隊列容量,默認為無限大
spring.task.execution.pool.max-size # 最大線程數,默認為無限大
這三個參數的關系如下:
如果當前要執行的任務數超過core-size,則任務會放到隊列里面等待執行,等核心線程中有任務執行完成之后,再取出隊列中的任務進行調度執行。
如果等待隊列已經滿了,再收到新任務時,則核心線程會自動擴容,最大擴展到max-size。

spring.task.execution.pool.allow-core-thread-timeout # 是否允許回收空閑的線程,默認為true
spring.task.execution.pool.keep-alive # 空閑的線程可以保留多少秒,默認為60。如果超過這個時間沒有任務調度,則線程會被回收
spring.task.execution.thread-name-prefix # 線程名前綴,默認為thread-

自定義線程調度器
如果不想使用Spring Boot自帶的線程調度器,可以通過實現AsyncConfigurer接口來定義自己的線程調度器。
示例代碼如下: 

@Configuration
@EnableAsync
public class AppConfig implements AsyncConfigurer {

  @Override
  public Executor getAsyncExecutor() {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setCorePoolSize(7);
    executor.setMaxPoolSize(42);
    executor.setQueueCapacity(11);
    executor.setThreadNamePrefix("MyExecutor-");
    executor.initialize();
    return executor;
  }

  @Override
  public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
    return MyAsyncUncaughtExceptionHandler();
  }
}

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM