平常求贊,感謝老闆。歡迎關注公衆號:實際上是白羊。乾貨持續更新中......java
在作業務時總會有這樣的場景:在特定時間去執行某些邏輯。這其實就是定時任務的應用場景,好比:須要每個月一日給用戶發上月數據總結等場景。spring
實現定時任務的技術不少多線程
開啓定時任務,可標註在啓動類或者任何配置類上(能掃描到對象上均可以)併發
配置具體的任務執行規則,可標註在能被掃描的類的方法上,屬性有:app
定時任務的場景:延遲執行、必定頻率執行、指定時間執行框架
這裏的cron表達式即爲了描述任務執行的時間規則。cron由6-7個元素組成,他們之間使用空格來分割,以此表明:異步
除了上面的數字元素值還有下面幾個特殊的元素值:spring-boot
瞭解了上面的表達式規則就能夠寫出知足條件的cron表達式了,建議多設計幾個場景練習下ui
若是就按上面的配置寫好任務A(fixedRate=2000)和任務B(fixedRate=3000)直接啓動執行的話,會存在如下問題:this
上面的問題都不能讓咱們的任務按照各自規定的執行計劃去執行,歸根到底仍是全部的任務都在一個線程裏進行,因此作不到異步的併發執行,那這是就能夠經過多線程來實現各個任務之間異步的併發執行
這裏咱們可使用Spring的@Async註解來實現異步
SpringBoot一樣支持@Async來實現異步(增長了自動配置可直接使用)
標註在啓動類或配置類上,表是開啓異步
可標註在類上(能被spring容器掃描到的類上)或方法上
標註在類上則這個類裏的方法都被表示爲異步
須要返回值:
@Async public Future<String> doTaskOne() throws Exception { return new AsyncResult<>("任務一完成"); }
使用@Async來實現異步,其底層仍是使用了多線程來進行實現的,那麼這個多線程或者線程池是在哪裏設置或配置的呢?咱們都直到SpringBoot加入了大量的自動配置,咱們在spring-boot-autoconfigure包下面能夠找到task包下的TaskExecutionAutoConfiguration類中:
@Lazy @Bean(name = { APPLICATION_TASK_EXECUTOR_BEAN_NAME, AsyncAnnotationBeanPostProcessor.DEFAULT_TASK_EXECUTOR_BEAN_NAME }) @ConditionalOnMissingBean(Executor.class) //這個註解的意思:當在容器中沒有發現Executor這個類則會加載這個bean,能夠理解爲此處爲默認缺省對象 //返回的是一個spring爲咱們提供的線程池 public ThreadPoolTaskExecutor applicationTaskExecutor(TaskExecutorBuilder builder) { return builder.build(); }
找到TaskExecutorBuilder:
@Bean @ConditionalOnMissingBean public TaskExecutorBuilder taskExecutorBuilder() { TaskExecutionProperties.Pool pool = this.properties.getPool(); TaskExecutorBuilder builder = new TaskExecutorBuilder(); builder = builder.queueCapacity(pool.getQueueCapacity()); builder = builder.corePoolSize(pool.getCoreSize()); builder = builder.maxPoolSize(pool.getMaxSize()); builder = builder.allowCoreThreadTimeOut(pool.isAllowCoreThreadTimeout()); builder = builder.keepAlive(pool.getKeepAlive()); builder = builder.threadNamePrefix(this.properties.getThreadNamePrefix()); builder = builder.customizers(this.taskExecutorCustomizers.orderedStream()::iterator); builder = builder.taskDecorator(this.taskDecorator.getIfUnique()); return builder; }
這裏的properties是在TaskExecutionProperties加載進來的,默認的參數:
private int queueCapacity = Integer.MAX_VALUE; private int coreSize = 8; private int maxSize = Integer.MAX_VALUE; private boolean allowCoreThreadTimeout = true;
根據下面可知,也能夠從yml/properties文件中自定義配置
@ConfigurationProperties("spring.task.execution")
除了上面的方法咱們還能夠定義本身的Bean來替換默認缺省Bean,根據@ConditionalOnMissingBean(Executor.class)可知,咱們只須要在配置類里加上:
@Bean public Executor taskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(核心線程數量); executor.setMaxPoolSize(最大線程數量); executor.setQueueCapacity(任務隊列大小); executor.initialize(); return executor; }
根據上面的介紹,要實現異步的定時任務就能夠展開,任務方法上面加上@Async來實現
點個贊啊親
若是你認爲本文對你有幫助,能夠「在看/轉發/贊/star」,多謝若是你還發現了更好或不一樣的想法,還能夠在留言區一塊兒探討下
歡迎關注公衆號:「實際上是白羊」乾貨持續更新中......