SpringBoot @Schedule多线程

        @Schedule创建的定时任务默认单线程的同步执行,虽然可以通过SchedulingConfigurer指定线程的个数,但是当代码运行起来时还是同步执行,同一个调度任务还需要阻塞等待上一次任务执行完成之后才能继续执行下一次任务。不同调度任务也是同一样的,需要阻塞等待上一个调度任务完成之后,才可以继续执行下一个调度任务。所以我们需要开始定时器的多线程异步执行。

1.Java多线程方式

        通过在@Schedule注解方法,修改成异步执行,可以使用Java多线程

@SpringBootApplication
@Slf4j
@EnableScheduling
public class MyScheduledProgram {

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

    /**
     * 每两秒执行一次
     */
    @Scheduled(fixedRate = 2000L)
    public void myScheduledGet() {
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        executorService.submit(() -> {
            log.info("++++++++++++MyScheduledGet");
        });
    }

    ExecutorService executorServiceSet = Executors.newSingleThreadExecutor();

    /**
     * 每三秒执行一次
     *
     * @throws InterruptedException
     */
    @Scheduled(fixedRate = 3000L)
    public void myScheduledSet() {
        executorServiceSet.submit(() -> {
            int sleepTime = Double.valueOf(Math.random() * 10).intValue();
            log.info("==============MyScheduledSet; sleep time(second):{}", sleepTime);
            try {
                Thread.sleep(sleepTime * 1000);
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        });

    }
}

 

 2.@EnableAsync和@Async

        对于同一个调度任务的执行,如果任务的执行时间超过该任务的下一次执行时间,会启动另外一个线程去执行,不会跳造成任务丢失(前提:有空闲线程去执行)
        对于多个不同的调度任务在执行时间上有交集,在执行任务A的过程中,到了任务B的执行时间,任务B不会阻塞,不需要等待任务A完成,会启动另外一个线程去执行任务B(前提:有空闲线程去执行)

@SpringBootApplication
@Slf4j
@EnableScheduling
@EnableAsync
public class MyScheduledProgram {

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

    /**
     * 每两秒执行一次
     */
    @Scheduled(fixedRate = 2000L)
    @Async("taskAsyncScheduler")
    public void myScheduledGet() {
        log.info("++++++++++++MyScheduledGet");
    }


    /**
     * 每三秒执行一次
     *
     * @throws InterruptedException
     */
    @Scheduled(fixedRate = 3000L)
    // 指定值TaskScheduler使用默认
    @Async("taskAsyncScheduler")
    public void myScheduledSet() {
        int sleepTime = Double.valueOf(Math.random() * 10).intValue();
        log.info("==============MyScheduledSet; sleep time(second):{}", sleepTime);
        try {
            Thread.sleep(sleepTime * 1000);
        } catch (Exception ex) {
            ex.printStackTrace();
        }

    }

    @Bean("taskAsyncScheduler")
    public TaskScheduler taskScheduler() {
        ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
        taskScheduler.setPoolSize(3);
        return taskScheduler;
    }
}

3.注入TaskScheduler定时任务线程池,增加线程个数

@SpringBootApplication
@Slf4j
@EnableScheduling
public class MyScheduledProgram {

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

    /**
     * 每两秒执行一次
     */
    @Scheduled(fixedRate = 2000L)
    public void myScheduledGet() {
        log.info("++++++++++++MyScheduledGet");
    }


    /**
     * 每三秒执行一次
     *
     * @throws InterruptedException
     */
    @Scheduled(fixedRate = 3000L)
    public void myScheduledSet() {
        int sleepTime = Double.valueOf(Math.random() * 10).intValue();
        log.info("==============MyScheduledSet; sleep time(second):{}", sleepTime);
        try {
            Thread.sleep(sleepTime * 1000);
        } catch (Exception ex) {
            ex.printStackTrace();
        }

    }

    @Bean
    public TaskScheduler taskScheduler() {
        ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
        taskScheduler.setPoolSize(3);
        return taskScheduler;
    }
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值