從Spring的@Scheduled提及

經過Spring的@Scheduled能夠建立定時任務。spring

  • 引入 xmlns:task 命名空間;
  • 在task任務執行類引入註解:@Component@EnableScheduling;
  • 配置定時執行任務:@Scheduled(cron = "0/10 * * * * *");

任務執行task:多線程

@Component
@EnableScheduling
public class TestDaemon {

    @Scheduled(cron = "0/10 * * * * *")
    public void testRunTask(){
        try {
            Thread.sleep(20000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        DateFormat df = new SimpleDateFormat("HH:mm:ss");
        System.out.println(df.format(new Date()) + "********A任務每10秒執行一次進入測試");
    }
}

    @Scheduled(cron = "0/5 * * * * *")
    private void fullQueueTask() {
        System.out.println(new SimpleDateFormat("HH:mm:ss").format(new Date()) + "********B任務每5秒執行一次進入測試");
    }

跑起來:併發

13:21:25********B任務每5秒執行一次進入測試
13:21:30********B任務每5秒執行一次進入測試
13:21:50********A任務每10秒執行一次進入測試
13:21:50********B任務每5秒執行一次進入測試
13:21:55********B任務每5秒執行一次進入測試
13:22:00********B任務每5秒執行一次進入測試
13:22:20********A任務每10秒執行一次進入測試
13:22:20********B任務每5秒執行一次進入測試
13:22:25********B任務每5秒執行一次進入測試

咱們發現B並無每隔5秒鐘執行,而是當A任務啓動後,B任務須要等待A任務執行完成以後繼續執行。 這是由於默認的@Scheduled是單線程執行的,全部任務須要互相排隊。異步

咱們在業務上確定須要不一樣調度任務有本身的節奏,單線程是知足不了了,Spring爲咱們提供了多線程的調度方式。測試

XML:線程

<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns="http://www.springframework.org/schema/beans"
       xmlns:task="http://www.springframework.org/schema/task"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd">

    <task:annotation-driven scheduler="myScheduler" />
    <!-- 配置任務線程池 -->
    <task:scheduler id="myScheduler" pool-size="5" />
</beans>

引入xml:code

<import resource="server-task.xml" />

再次執行:orm

13:26:00********B任務每5秒執行一次進入測試
13:26:05********B任務每5秒執行一次進入測試
13:26:10********B任務每5秒執行一次進入測試
13:26:15********B任務每5秒執行一次進入測試
13:26:20********B任務每5秒執行一次進入測試
13:26:20********A任務每10秒執行一次進入測試
13:26:25********B任務每5秒執行一次進入測試
13:26:30********B任務每5秒執行一次進入測試
13:26:35********B任務每5秒執行一次進入測試
13:26:40********B任務每5秒執行一次進入測試
13:26:45********B任務每5秒執行一次進入測試
13:26:50********A任務每10秒執行一次進入測試
13:26:50********B任務每5秒執行一次進入測試
13:26:55********B任務每5秒執行一次進入測試

咱們發現B任務是按照本身的節奏進行,每隔5秒執行一次。server

關於task:executor和task:scheduler的區別

默認任務調度是單線程的,經過task:scheduler咱們能夠建立一個對應的任務調度線程池執行任務,這樣多任務調度就不須要串行執行了。xml

當咱們採用@Async異步執行邏輯時,使用的線程是task:executor中的線程,若是用@Async修飾一個調度任務,則調度線程池就會不用當前調度線程來執行,而是交給 task:executor 這個執行線程池來執行。

因此配置 task:scheduler 參數的線程池,只和調度任務有關,是爲了根據任務總數來分配調度線程池的大小; 而配置 task:executor ,只和@Async異步任務有關,是爲了某個任務若是要異步的執行時,實現當前任務內的多線程併發。

<task:annotation-driven scheduler="myScheduler" executor="myExecutor"/>
    <!-- 配置任務線程池 -->
    <task:scheduler id="myScheduler" pool-size="20" />
    <task:executor id="myExecutor" pool-size="15-20" queue-capacity="1000" keep-alive="100ms" rejection-policy="CALLER_RUNS"/>
相關文章
相關標籤/搜索