从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"/>
相关文章
相关标签/搜索