Ric*_*mon 1 java multithreading timer
我有一个计时器线程,需要在一天中的特定时刻运行,以便与数据库进行增量复制.现在它在小时,小时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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
通过TimerRunner.initialize()在服务器启动和调用时调用来启动此过程TimerRunner.destroy().
我创建了一个完整的复制过程(而不是增量),我想在一天中的某个时刻运行,比如说凌晨2点.如何改变上面的代码呢?我认为这应该是非常简单的事情,如果它现在是凌晨2点左右,并且已经很长一段时间,因为我完成了复制,然后现在就做,但我不能得到if.
请注意,有时复制过程需要更长时间才能完成.有时超过15分钟,在凌晨2点左右跑步时出现问题.
恕我直言,如果它做了不同的事情,它不应该是相同的runnable.创建一些通用抽象类和两个子类,每个子类都具有特定的行为.然后让您的调度逻辑在适当的时间安排适当的线程.
否则,您有一个具有两个职责且需要了解调度的对象.
我个人也会从当前的getDelay()和一些复制调度管理器对象中获取调度逻辑,该对象也会保持状态(例如,最近执行的内容).
最后,你可能想要为你的调度程序使用库的东西,我觉得你正在重新发明一些轮子.