hedLock让ThreadPoolTask​​Schedule

hedLock让ThreadPoolTask​​Schedule

本文介绍了使用ShedLock让ThreadPoolTask​​Scheduler处理多个调度任务的分布式锁问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道 ShedLock 可以用来做与 Spring 集成的分布式锁:

I know ShedLock could be used to do distributed lock integrated with Spring as:

    @Scheduled(cron = "*/5 * * * * ?")
    @SchedulerLock(name = "exampleLock", lockAtLeastForString = "20000", lockAtMostForString = "30000")
    private void exampleMethod(){
         System.out.println(String.format("[%s] test job runs...", new Date()));
}

但就我而言,我想分别独立地执行从数据库读取的多个计划任务(Cron)并由 ThreadPoolTask​​Scheduler 处理.我编码如下,但是它不能处理多个实例来执行每个计划任务.Spring有没有办法实现这个目标?任何想法都将受到高度赞赏.

But for my case I'd like to execute multiple schedule tasks(Crons) read from Database and process by ThreadPoolTaskScheduler separately and independently. I coded as below, however it doesn't work dealing with multiple instances to execute each scheduled task. Is there any way with Spring or without to achieve this? Any thought will be highly appreciated.

public class ExampleShedLock implements SchedulingConfigurer {

    @Resource
    private ScheduleTaskRepository scheduleTaskRepository;

    @Resource
    private TaskScheduler threadPoolTaskScheduler;

    @Override
    public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {

        scheduledTaskRegistrar.setTaskScheduler(getThreadPoolTaskScheduler());
        Map<String, String> dataMap = scheduleTaskRepository
                .selectExpressionByIsActive();
        dataMap.forEach(
                (key, expression) -> scheduledTaskRegistrar.getScheduler()
                        .schedule(() -> scheduledTask(),
                                (TriggerContext triggerContext) -> {
                                    CronTrigger trigger = new CronTrigger(
                                            expression,
                                            TimeZone.getTimeZone(ZoneOffset.UTC));
                                    return trigger.nextExecutionTime(triggerContext);
                                }));
    }

    @SchedulerLock(name = "TaskScheduler",
            lockAtLeastFor = 20*1000, lockAtMostFor = 30*1000)
    private void scheduledTask() {

        System.out.println(
                Thread.currentThread().getName() + " - " + Calendar
                        .getInstance()
                        .getTime();

    }


    @Bean(name = "threadPoolTaskScheduler")
    public TaskScheduler getThreadPoolTaskScheduler() {
        ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
        taskScheduler.setPoolSize(10);
        taskScheduler.setThreadNamePrefix("Scheduled-");
        taskScheduler.setRejectedExecutionHandler(new
        ThreadPoolExecutor.CallerRunsPolicy());
        taskScheduler.setWaitForTasksToCompleteOnShutdown(true);
        taskScheduler.setAwaitTerminationSeconds(60);
        taskScheduler.initialize();
        return taskScheduler;
    }
}

推荐答案

我终于想出了一种方法来完成查询.我可以使用自定义的 LockConfigurationExtractor 将 TaskScheduler 包装到 LockableTaskScheduler 并像这样手动安排每个 taskScheduler,而不是使用 @SchedulerLock 注释:

I finally figure out one way to accomplish the query. Rather than to use @SchedulerLock annotation, I could wrap the TaskScheduler to LockableTaskScheduler with your customized LockConfigurationExtractor and schedule each taskScheduler manually like this:

DefaultLockManager defaultLockManager = new DefaultLockManager(lockProvider,
            customizedLockConfigurationExtractor);
return new LockableTaskScheduler(taskScheduler, defaultLockManager);

这篇关于使用ShedLock让ThreadPoolTask​​Scheduler处理多个调度任务的分布式锁问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-07 03:32