Don't start shutdown hook threads more than once.

This commit is contained in:
akwizgran
2011-11-19 17:23:18 +00:00
parent bc7d882af6
commit b2226067e1
2 changed files with 20 additions and 12 deletions

View File

@@ -15,14 +15,18 @@ class ShutdownManagerImpl implements ShutdownManager {
hooks = new HashMap<Integer, Thread>();
}
public synchronized int addShutdownHook(Runnable runnable) {
public synchronized int addShutdownHook(Runnable r) {
int handle = nextHandle++;
Thread hook = new Thread(runnable);
Thread hook = createThread(r);
hooks.put(handle, hook);
Runtime.getRuntime().addShutdownHook(hook);
return handle;
}
protected Thread createThread(Runnable r) {
return new Thread(r);
}
public synchronized boolean removeShutdownHook(int handle) {
Thread hook = hooks.remove(handle);
if(hook == null) return false;

View File

@@ -45,9 +45,14 @@ class WindowsShutdownManagerImpl extends ShutdownManagerImpl {
}
@Override
public synchronized int addShutdownHook(Runnable runnable) {
public synchronized int addShutdownHook(Runnable r) {
if(!initialised) initialise();
return super.addShutdownHook(new RunOnce(runnable));
return super.addShutdownHook(r);
}
@Override
protected Thread createThread(Runnable r) {
return new StartOnce(r);
}
// Locking: this
@@ -122,19 +127,18 @@ class WindowsShutdownManagerImpl extends ShutdownManagerImpl {
}
}
private static class RunOnce implements Runnable {
private static class StartOnce extends Thread {
private final Runnable runnable;
private final AtomicBoolean called = new AtomicBoolean(false);
private RunOnce(Runnable runnable) {
this.runnable = runnable;
private StartOnce(Runnable r) {
super(r);
}
public void run() {
// Ensure the runnable only runs once
if(called.getAndSet(true)) return;
runnable.run();
@Override
public void start() {
// Ensure the thread is only started once
if(!called.getAndSet(true)) super.start();
}
}