filebot/source/net/sourceforge/tuned/Timer.java

103 lines
2.5 KiB
Java
Raw Normal View History

2008-12-30 16:43:37 +00:00
package net.sourceforge.tuned;
import java.util.concurrent.ScheduledFuture;
2008-12-30 16:43:37 +00:00
import java.util.concurrent.ScheduledThreadPoolExecutor;
2009-10-15 15:18:57 +00:00
import java.util.concurrent.ThreadFactory;
2008-12-30 16:43:37 +00:00
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
2008-12-30 16:43:37 +00:00
public abstract class Timer implements Runnable {
2009-10-15 15:18:57 +00:00
private final ThreadFactory threadFactory = new DefaultThreadFactory("Timer", Thread.NORM_PRIORITY, true);
2008-12-30 16:43:37 +00:00
2009-10-15 15:18:57 +00:00
private ScheduledThreadPoolExecutor executor;
private ScheduledFuture<?> scheduledFuture;
2008-12-30 16:43:37 +00:00
private Thread shutdownHook;
2008-12-30 16:43:37 +00:00
public synchronized void set(long delay, TimeUnit unit, boolean runBeforeShutdown) {
2009-10-15 15:18:57 +00:00
// create executor if necessary
if (executor == null) {
executor = new ScheduledThreadPoolExecutor(1, threadFactory);
}
2008-12-30 16:43:37 +00:00
2009-10-15 15:18:57 +00:00
// cancel existing future task
if (scheduledFuture != null) {
scheduledFuture.cancel(true);
}
Runnable runnable = this;
2008-12-30 16:43:37 +00:00
if (runBeforeShutdown) {
try {
addShutdownHook();
} catch (Exception e) {
// may fail if running with restricted permissions
Logger.getLogger(getClass().getName()).log(Level.WARNING, e.getClass().getName() + ": " + e.getMessage());
}
2008-12-30 16:43:37 +00:00
// remove shutdown hook after execution
2009-10-15 15:18:57 +00:00
runnable = new Runnable() {
2008-12-30 16:43:37 +00:00
@Override
public void run() {
try {
Timer.this.run();
} finally {
2009-10-15 15:18:57 +00:00
cancel();
2008-12-30 16:43:37 +00:00
}
}
};
} else {
try {
// remove existing shutdown hook, if any
removeShutdownHook();
} catch (Exception e) {
// may fail if running with restricted permissions
Logger.getLogger(getClass().getName()).log(Level.WARNING, e.getClass().getName() + ": " + e.getMessage());
}
2008-12-30 16:43:37 +00:00
}
2009-10-15 15:18:57 +00:00
scheduledFuture = executor.schedule(runnable, delay, unit);
2008-12-30 16:43:37 +00:00
}
2008-12-30 16:43:37 +00:00
public synchronized void cancel() {
removeShutdownHook();
2009-10-15 15:18:57 +00:00
// stop executor
executor.shutdownNow();
scheduledFuture = null;
executor = null;
2008-12-30 16:43:37 +00:00
}
2008-12-30 16:43:37 +00:00
private synchronized void addShutdownHook() {
if (shutdownHook == null) {
shutdownHook = new Thread(this);
Runtime.getRuntime().addShutdownHook(shutdownHook);
}
}
2008-12-30 16:43:37 +00:00
private synchronized void removeShutdownHook() {
if (shutdownHook != null) {
try {
if (shutdownHook != Thread.currentThread()) {
// can't remove shutdown hooks anymore, once runtime is shutting down,
// so don't remove the shutdown hook, if we are running on the shutdown hook
Runtime.getRuntime().removeShutdownHook(shutdownHook);
}
} finally {
shutdownHook = null;
}
}
}
}