diff --git a/core/java/src/net/i2p/I2PAppContext.java b/core/java/src/net/i2p/I2PAppContext.java
index 99bbd53c72deb2125738f6b88f9ebf01be2f12c5..7df62046c8c79d64008a3b4e61a23461a3a95737 100644
--- a/core/java/src/net/i2p/I2PAppContext.java
+++ b/core/java/src/net/i2p/I2PAppContext.java
@@ -906,6 +906,13 @@ public class I2PAppContext {
     public void addShutdownTask(Runnable task) {
         _shutdownTasks.add(task);
     }
+
+    /**
+     *  @since 0.9.53
+     */
+    public void removeShutdownTask(Runnable task) {
+        _shutdownTasks.remove(task);
+    }
     
     /**
      *  @return an unmodifiable Set
diff --git a/core/java/src/net/i2p/util/SimpleTimer2.java b/core/java/src/net/i2p/util/SimpleTimer2.java
index b6c6deaef72a5b926db4ad8197b24506c9e10974..f2723dbb73b7e8c012836b8e958e83624e694b4e 100644
--- a/core/java/src/net/i2p/util/SimpleTimer2.java
+++ b/core/java/src/net/i2p/util/SimpleTimer2.java
@@ -41,6 +41,8 @@ public class SimpleTimer2 {
     private final String _name;
     private final AtomicInteger _count = new AtomicInteger();
     private final int _threads;
+    private final I2PAppContext _context;
+    private final Runnable _shutdown;
 
     /**
      *  To be instantiated by the context.
@@ -64,14 +66,15 @@ public class SimpleTimer2 {
      *  @since 0.9
      */
     protected SimpleTimer2(I2PAppContext context, String name, boolean prestartAllThreads) {
+        _context = context;
         _name = name;
         long maxMemory = SystemVersion.getMaxMemory();
         _threads = (int) Math.max(MIN_THREADS, Math.min(MAX_THREADS, 1 + (maxMemory / (32*1024*1024))));
         _executor = new CustomScheduledThreadPoolExecutor(_threads, new CustomThreadFactory());
         if (prestartAllThreads)
             _executor.prestartAllCoreThreads();
-        // don't bother saving ref to remove hook if somebody else calls stop
-        context.addShutdownTask(new Shutdown());
+        _shutdown = new Shutdown();
+        context.addShutdownTask(_shutdown);
     }
     
     /**
@@ -79,7 +82,7 @@ public class SimpleTimer2 {
      */
     private class Shutdown implements Runnable {
         public void run() {
-            stop();
+            stop(false);
         }
     }
 
@@ -89,6 +92,20 @@ public class SimpleTimer2 {
      * Cannot be restarted.
      */
     public void stop() {
+        stop(true);
+    }
+
+    /**
+     * Stops the SimpleTimer.
+     * Subsequent executions should not throw a RejectedExecutionException.
+     * Cannot be restarted.
+     *
+     * @param removeTask true to unregister the shutdown hook
+     * @since 0.9.53
+     */
+    private void stop(boolean removeTask) {
+        if (removeTask)
+            _context.removeShutdownTask(_shutdown);
         _executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());
         _executor.shutdownNow();
     }