* don't keep unused threads around
This commit is contained in:
parent
d841b76fc4
commit
5bb45541a8
|
@ -4,39 +4,44 @@ package net.sourceforge.tuned;
|
||||||
|
|
||||||
import java.util.concurrent.ScheduledFuture;
|
import java.util.concurrent.ScheduledFuture;
|
||||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||||
|
import java.util.concurrent.ThreadFactory;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
|
||||||
public abstract class Timer implements Runnable {
|
public abstract class Timer implements Runnable {
|
||||||
|
|
||||||
private final ScheduledThreadPoolExecutor executor;
|
private final ThreadFactory threadFactory = new DefaultThreadFactory("Timer", Thread.NORM_PRIORITY, true);
|
||||||
|
|
||||||
|
private ScheduledThreadPoolExecutor executor;
|
||||||
private ScheduledFuture<?> scheduledFuture;
|
private ScheduledFuture<?> scheduledFuture;
|
||||||
private Thread shutdownHook;
|
private Thread shutdownHook;
|
||||||
|
|
||||||
|
|
||||||
public Timer() {
|
|
||||||
executor = new ScheduledThreadPoolExecutor(1, new DefaultThreadFactory("Timer", Thread.NORM_PRIORITY, true));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public synchronized void set(long delay, TimeUnit unit, boolean runBeforeShutdown) {
|
public synchronized void set(long delay, TimeUnit unit, boolean runBeforeShutdown) {
|
||||||
removeScheduledFuture();
|
// create executor if necessary
|
||||||
|
if (executor == null) {
|
||||||
|
executor = new ScheduledThreadPoolExecutor(1, threadFactory);
|
||||||
|
}
|
||||||
|
|
||||||
Runnable r = this;
|
// cancel existing future task
|
||||||
|
if (scheduledFuture != null) {
|
||||||
|
scheduledFuture.cancel(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
Runnable runnable = this;
|
||||||
|
|
||||||
if (runBeforeShutdown) {
|
if (runBeforeShutdown) {
|
||||||
addShutdownHook();
|
addShutdownHook();
|
||||||
|
|
||||||
// remove shutdown hook after execution
|
// remove shutdown hook after execution
|
||||||
r = new Runnable() {
|
runnable = new Runnable() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
Timer.this.run();
|
Timer.this.run();
|
||||||
} finally {
|
} finally {
|
||||||
removeShutdownHook();
|
cancel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -45,25 +50,18 @@ public abstract class Timer implements Runnable {
|
||||||
removeShutdownHook();
|
removeShutdownHook();
|
||||||
}
|
}
|
||||||
|
|
||||||
scheduledFuture = executor.schedule(r, delay, unit);
|
scheduledFuture = executor.schedule(runnable, delay, unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public synchronized void cancel() {
|
public synchronized void cancel() {
|
||||||
removeScheduledFuture();
|
|
||||||
removeShutdownHook();
|
removeShutdownHook();
|
||||||
}
|
|
||||||
|
|
||||||
|
// stop executor
|
||||||
|
executor.shutdownNow();
|
||||||
|
|
||||||
private synchronized void removeScheduledFuture() {
|
scheduledFuture = null;
|
||||||
if (scheduledFuture != null) {
|
executor = null;
|
||||||
try {
|
|
||||||
scheduledFuture.cancel(true);
|
|
||||||
executor.purge();
|
|
||||||
} finally {
|
|
||||||
scheduledFuture = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue