@@ -0,0 +1,1365 @@
+package com.netflix.util.concurrent;%0A%0Aimport java.util.Timer;%0A%0Aimport org.slf4j.Logger;%0Aimport org.slf4j.LoggerFactory;%0A%0A%0A%0A/**%0A * %0A * ShutdownEnabledTimer class handles runtime shutdown issues.%0A * %0A * Apparently, adding a runtime shutdown hook will create a global reference%0A * which can cause memory leaks if not cleaned up.%0A * %0A * This abstraction provides a wrapped mechanism to manage those runtime shutdown hooks.%0A * %0A * @author jzarfoss%0A *%0A */%0Apublic class ShutdownEnabledTimer extends Timer%7B%0A%0A%09%0A%09private static final Logger LOGGER = LoggerFactory.getLogger(ShutdownEnabledTimer.class);%0A%09%0A%09private Thread cancelThread;%0A%09private String name;%0A%09%0A%09public ShutdownEnabledTimer(String name, boolean daemon)%7B%0A%09%09super(name, daemon);%0A%09%09%0A%09%09this.name = name;%0A%09%09%0A%09%09this.cancelThread = new Thread(new Runnable() %7B%0A%09           public void run()%0A%09           %7B%0A%09        %09   ShutdownEnabledTimer.super.cancel();%0A%09           %7D%0A%09       %7D);%0A%09%09%0A%09%09LOGGER.info(%22Shutdown hook installed for: %7B%7D%22, this.name);%0A%09%09%0A%09%09Runtime.getRuntime().addShutdownHook(this.cancelThread);%0A%09%7D%0A%09%0A%09@Override%0A%09public void cancel()%7B%0A%09%09super.cancel();%0A%09%09%0A%09%09LOGGER.info(%22Shutdown hook removed for: %7B%7D%22, this.name);%0A%09%09%0A%09%09try%7B%0A%09%09%09Runtime.getRuntime().removeShutdownHook(this.cancelThread);%0A%09%09%7Dcatch(IllegalStateException ise)%7B%0A%09%09%09LOGGER.info(%22Exception caught (might be ok if at shutdown)%22, ise);%0A%09%09%7D%0A%09%0A%09%7D%0A%09%0A%7D%0A

Add ShutdownEnabledTimer