Java将作业调度为在特定时间运行最长时间段

2022-08-05 00:00:00 scheduled-tasks java spring-boot

我正在尝试安排一个应该每10秒运行一次的任务。但是,此任务应该具有动态允许的周期执行时间。换句话说,如果允许的最大时间为5秒,并且任务运行时间超过5秒,则应终止/关闭该任务。

我曾尝试使用具有cron时间的@Schedule,但无论我尝试什么,一旦它运行,我就无法终止它。但是,有人建议我不要使用@Schedule,而使用ScheduledExecutorService创建一个普通任务,但我不知道如何操作。

我原来的方法是这样的:

    @Scheduled(cron = "0/10 * * * * ?")
    @Transactional
    public void testMethod(Integer period) {
        ThreadPoolTaskScheduler scheduler;

        scheduler.setAwaitTerminationSeconds(period);
        scheduler.setWaitForTasksToCompleteOnShutdown(false);

        importantMethod();
        
    }

我尝试将其重写如下:

public void testMethod(){
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);            
  scheduler.scheduleAtFixedRate(importantMethod(), delay,
                                  period, TimeUnit.SECONDS);
}

但是,我不确定如何将其设置为每10秒或每5分钟运行一次,并且仅在超过允许的最大时间后才将其关闭。

我们将非常感谢您的帮助。


解决方案

根据描述,我的假设:

  1. 任务应每10秒运行一次
  2. 任务的最大超时时间应为5秒
  3. 最大超时应可配置

应用程序中的配置。属性

scheduler.timeout = 5000

代码


    @Value("${scheduler.timeout}")
    private Long timeout;
    
    @Scheduled(cron = "0/10 * * * * ?")
    public void taskScheduler() {
        System.out.println("Task Started: " + LocalDateTime.now());
        this.executeTask((Callable<Object>) () -> {
            TimeUnit.MILLISECONDS.sleep(3000);//Change values for testing: sleep time
            System.out.println("Task Worked: " + LocalDateTime.now());
            return true;
        }, timeout);
    }
    
    ExecutorService service = Executors.newFixedThreadPool(1);
    ScheduledExecutorService canceller = Executors.newSingleThreadScheduledExecutor();
    
    public <T> Future<T> executeTask(Callable<T> c, long timeoutMS) {
        final Future<T> future = service.submit(c);
        canceller.schedule(() -> {
            if (!future.isDone())
                System.out.println("Task Cancelled: " + LocalDateTime.now());
            future.cancel(true);
            return "done";
        }, timeoutMS, TimeUnit.MILLISECONDS);
        return future;
    }

输出
任务在3秒内完成时(休眠时间)

Task Started: 2022-02-06T22:42:30.010704200
Task Worked: 2022-02-06T22:42:33.014775100

任务在6秒内完成时(睡眠时间)

Task Started: 2022-02-06T22:47:30.003249500
Task Cancelled: 2022-02-06T22:47:35.013195900

相关文章