java如何使线程在x:00X:15X:30和x:45运行在2:00做一些不同的事情
我有一个计时器线程,它需要在一天中的特定时刻运行,以便对数据库执行增量复制。现在它按小时运行,每小时15分钟,每小时30分钟,每小时45分钟。这是我的代码,工作正常:
public class TimerRunner implements Runnable {
private static final Semaphore lock = new Semaphore(1);
private static final ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
public static void initialize() {
long delay = getDelay();
executor.schedule(new TimerRunner(), delay, TimeUnit.SECONDS);
}
public static void destroy() {
executor.shutdownNow();
}
private static long getDelay() {
Calendar now = Calendar.getInstance();
long p = 15 * 60; // run at 00, 15, 30 and 45 minutes past the hour
long second = now.get(Calendar.MINUTE) * 60 + now.get(Calendar.SECOND);
return p - (second % p);
}
public static void replicate() {
if (lock.tryAcquire()) {
try {
Thread t = new Thread(new Runnable() {
public void run() {
try {
// here is where the magic happens
} finally {
lock.release();
}
}
});
t.start();
} catch (Exception e) {
lock.release();
}
} else {
throw new IllegalStateException("already running a replicator");
}
}
public void run() {
try {
TimerRunner.replicate();
} finally {
long delay = getDelay();
executor.schedule(new TimerRunner(), delay, TimeUnit.SECONDS);
}
}
}
这个过程是通过在服务器启动时调用TimerRunner.initialize()
并调用TimerRunner.destroy()
来启动的
我已经创建了一个完整的复制过程(而不是增量复制),我希望在一天中的某个时刻(比如凌晨2点)运行该过程。如何更改上述代码以实现此目的?我认为这应该是非常简单的事情,比如如果现在是凌晨2点左右,而且我已经很长时间没有做完整的复制了,那么现在就做吧,但是我不能得到正确的if
请注意,有时复制过程需要更长的时间才能完成。有时超过15分钟,造成凌晨2:00左右跑步时出现问题
# 1 楼答案
嗯,如果它做了一些不同的事情,它不应该是相同的可运行的。创建一些泛型抽象类和两个子类,每个子类都有特定的行为。然后让调度逻辑在适当的时间调度适当的线程
否则,您的对象有两个职责,需要了解调度
我个人也会将调度逻辑从您当前的getDelay()中取出,放入一些replication scheduling manager对象中,该对象也会维护状态(例如,最近执行的内容)
最后,您可能想为您的调度程序使用库中的东西,我觉得您正在重新发明一些轮子
# 2 楼答案
不要构建自己的计划程序,使用现有的计划程序
如果您想在Java中执行此操作,请使用quartz和调度2个单独的任务来执行在不同调度上运行的增量备份和完整备份
但是在您的情况下,一个简单的cron脚本就可以了。如果您在Windows上运行,请在Windows帮助文件中搜索
Scheduled Tasks
编辑
以下是避免同时运行完整和增量的crontab:
在shell脚本中,设置java环境并运行负责任务的java程序
Quartz调度程序可以进行非常精细的调整,其中一个标准调度程序完全模仿crontab。我将此作为练习留给读者
顺便说一句,我已安排您的完整备份在凌晨1点运行,请参见下面的原因
关于夏令时的注意事项
我不知道你在世界上的什么地方,如果你是少数幸运的人之一,你没有夏令时,否则就去当地时区管理局查询。在北美,标准到日光发生在凌晨2:00,标准到日光发生在凌晨3:00,因此,如果您的完全备份计划在凌晨2:00进行,那么一年中的某一天(S到D)您的完全备份将不会运行,而另一天(D到S)它将运行两次