How to make a thread that runs at x:00 x:15 x:30 and x:45 do something different at 2:00.

Posted by rmarimon on Stack Overflow See other posts from Stack Overflow or by rmarimon
Published on 2010-05-27T21:24:21Z Indexed on 2010/05/28 11:31 UTC
Read the original article Hit count: 313

Filed under:
|
|

I have a timer thread that needs to run at a particular moments of the day to do an incremental replication with a database. Right now it runs at the hour, 15 minutes past the hour, 30 minutes past the hour and 45 minutes past the hour. This is the code I have which is working ok:

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);
        }
    }

}

This process is started by calling TimerRunner.initialize() when a server starts and calling TimerRunner.destroy().

I have created a full replication process (as opposed to incremental) that I would like to run at a certain moment of the day, say 2:00am. How would change the above code to do this? I think that it should be very simple something like if it is now around 2:00am and it's been a long time since I did the full replication then do it now, but I can't get the if right.

Beware that sometimes the replicate process takes way longer to complete. Sometimes beyond the 15 minutes, posing a problem in running at around 2:00am.

© Stack Overflow or respective owner

Related posts about java

Related posts about multithreading