我有一个方法希望使用Spring运行一次,它需要在给定的java.util上运行。日期
(或LocalDateTime
)。我计划将该方法应该执行的所有日期持久化到数据源。它应该异步运行。
一种方法是每天检查数据库中的日期,如果日期已过且尚未执行,则执行该方法。有没有更好的方法?
我知道Spring提供了ThreadPoolTaskScheduler
和ThreadPool TaskExecutor
。我正在查看TaskScheduler
界面中的ScheduledFuture计划(可运行任务,日期开始时间)
。我需要创建Runnable
Spring托管bean来调用我的方法吗?或者有更简单的注释可以做到这一点吗?举个例子真的很有帮助。
(也看了这里。)
查看@Scheduled
注释。它可能会实现你想要的。
@Scheduled(cron="*/5 * * * * MON-FRI")
public void scheduledDateWork() {
Date date = new Date(); //or use DAO call to look up date in database
executeLogic(date);
}
克朗表达的例子来自另一个答案:
"0 0 * * * *" = the top of every hour of every day.
"*/10 * * * * *" = every ten seconds.
"0 0 8-10 * * *" = 8, 9 and 10 o'clock of every day.
"0 0/30 8-10 * * *" = 8:00, 8:30, 9:00, 9:30 and 10 o'clock every day.
"0 0 9-17 * * MON-FRI" = on the hour nine-to-five weekdays
"0 0 0 25 12 ?" = every Christmas Day at midnight
通过将计划日期外部化(到数据库),典型的计划实践(即基于cron的或固定的计划)不再适用。给定目标日期,您可以按如下方式准确地计划任务:
Date now = new Date();
Date next = ... get next date from external source ...
long delay = next.getTime() - now.getTime();
scheduler.schedule(Runnable task, delay, TimeUnit.MILLISECONDS);
剩下的就是创建一种有效的方法来调度每个新任务。下面有一个 TaskDispatcher 线程,它根据下一个 java.util.Date(您从数据库中读取)来调度每个任务。无需每天检查;此方法足够灵活,可以与存储在数据库中的任何计划方案一起使用。
接下来是说明该方法的工作代码。
使用的示例任务;在这种情况下,只是Hibernate一段固定的时间。当任务完成时,TaskDispatcher会通过Count下拉锁发出信号。
public class Task implements Runnable {
private final CountDownLatch completion;
public Task(CountDownLatch completion) {
this.completion = completion;
}
@Override
public void run() {
System.out.println("Doing task");
try {
Thread.sleep(60*1000); // Simulate the job taking 60 seconds
} catch (InterruptedException e) {
e.printStackTrace();
}
completion.countDown(); // Signal that the job is complete
}
}
调度程序负责读取下一个计划日期的数据库,启动可运行的 ScheduledFuture 并等待任务完成。
public class TaskDispatcher implements Runnable {
private static final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
private boolean isInterrupted = false;
@Override
public void run() {
while (!isInterrupted) {
Date now = new Date();
System.out.println("Reading database for next date");
Date next = ... read next data from database ...
//Date next = new Date(); // Used as test
//next.setTime(now.getTime()+10*1000); // Used as test
long delay = next.getTime() - now.getTime();
System.out.println("Scheduling next task with delay="+delay);
CountDownLatch latch = new CountDownLatch(1);
ScheduledFuture<?> countdown = scheduler.schedule(new Task(latch), delay, TimeUnit.MILLISECONDS);
try {
System.out.println("Blocking until the current job has completed");
latch.await();
} catch (InterruptedException e) {
System.out.println("Thread has been requested to stop");
isInterrupted = true;
}
if (!isInterrupted)
System.out.println("Job has completed normally");
}
scheduler.shutdown();
}
}
TaskDispatcher 的启动方式如下(使用 Spring Boot) - 像通常使用 Spring 一样启动线程:
@Bean
public TaskExecutor taskExecutor() {
return new SimpleAsyncTaskExecutor(); // Or use another one of your liking
}
@Bean
public CommandLineRunner schedulingRunner(TaskExecutor executor) {
return new CommandLineRunner() {
public void run(String... args) throws Exception {
executor.execute(new TaskDispatcher());
}
};
}
让我知道这种方法是否适用于您的用例。
问题内容: 我试图用不同的颜色在JCalendar中设置特定日期,具体取决于数据库中是否有针对该日期的计划,该日期在数据库中存储为“ yyyy-MM- dd”,我在这里看到过类似的帖子在stackOverflow上,但我无法使其正常工作。 我不确定“ component [day] .setBackground(Color.green)”的工作方式,以及如何将其设置为仅在数据库中已为其计划好的日期
问题内容: 我想在的日期选择器中禁用特定的日期。 我正在使用CSS作为组件。 我要禁用的日期将根据组合中先前值的选择而动态更改。 我相信应该可以,尽管不确定。 我怎样才能做到这一点 ? 问题答案: 我假设您正在使用Angular-UI中的指令。该属性使您可以禁用某些日期(例如,周末)。看到这个笨蛋http://plnkr.co/edit/gGAU0L?p=preview 如果要基于选择动态禁用日期
问题内容: 我正在尝试使用JQuery Ui禁用特定日期。但是,我没有运气,这是我的代码: 实例化datepicker对象 获取日历中要禁用的日期 它似乎没有用,我知道如何解决这个问题。干杯。 问题答案: 好像您在一个输入上调用了两次。很难遵循您的代码,但是如果您重新组织代码并删除第二个调用,那么一切都会正常进行:
我有以下ThreadPoolTaskExecator2配置 在我的公共类AdminService中,我有两个方法。 void triggerJob() 布尔执行sql(字符串sql) 如何将ThreadPoolTaskExecutor插入triggerJob方法,以便在第一个方法中调用executeSql时创建新线程。 在triggerjob中,我有一个基于条件调用executeSql的循环。 我
这可能很简单,但我无法获得所需的输出。 我正在使用下面这个简单的查询来获取一个项目编号的最新exp\u日期 第一次查询仅显示20年8月1日的以下结果 现在,我想筛选上述结果,以获得“特定”的最新exp\u日期(例如:20年8月1日),因此我将查询修改为: 但这给了我多行,如果我使用,它会获取所需的输出。 如何让过滤在这里为特定的工作?
我做了一个表单来更新历史数据和一个子表单,用来检查结果!除了一个小问题外,一切都很好。