Java tutorial
/* $Id$ Copyright (C) 2009-2010 Virginia Tech. All rights reserved. SEE LICENSE FOR MORE INFORMATION Author: Middleware Services Email: middleware@vt.edu Version: $Revision$ Updated: $Date$ */ package edu.vt.middleware.gator.server; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Executor; import java.util.concurrent.ThreadPoolExecutor; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * Implementation of {@link ThreadPoolExecutor} that always creates new threads * for handling {@link LoggingEventHandler} tasks. The primary purpose of this * class is to set up the name and, if possible, {@link MDC} of each worker * thread. * * @author Middleware Services * @version $Revision$ */ public class LoggingEventHandlerExecutor implements Executor { /** Number of ms to wait for each worker thread operations to terminate. */ protected static final int STOP_TIMEOUT = 2000; /** Logger instance. */ protected final Log logger = LogFactory.getLog(getClass()); /** List of running threads. */ private List<LoggingEventHandlerThread> runningThreads; /** Creates a new instance. */ public LoggingEventHandlerExecutor() { runningThreads = new ArrayList<LoggingEventHandlerThread>(); } /** {@inheritDoc}. */ public void execute(final Runnable command) { if (!(command instanceof LoggingEventHandler)) { throw new IllegalArgumentException("Only LoggingEventHandler supported."); } final LoggingEventHandlerThread runner = new LoggingEventHandlerThread((LoggingEventHandler) command); runningThreads.add(runner); runner.start(); } /** * Attempts to perform a clean shutdown of all running {@link * LoggingEventHandler} tasks. */ public void shutdown() { for (LoggingEventHandlerThread runner : runningThreads) { runner.getLoggingEventHandler().shutdown(); try { runner.join(STOP_TIMEOUT); } catch (InterruptedException e) { logger.warn("Timed out waiting for LoggingEventHandler shutdown"); } catch (Exception e) { logger.warn("Error on logging event handler shutdown: " + e.getMessage()); } } } /** * Extends a thread with additional thread local data about handler. * * @author Middleware Services * @version $Revision$ */ protected class LoggingEventHandlerThread extends Thread { /** Handler run by this instance. */ private LoggingEventHandler loggingEventHandler; /** * Creates a new logging event handler thread for the host at the given * address. * * @param target Runnable object controlled by this thread. * @param addr IP address of host whose logging events are being handled. */ public LoggingEventHandlerThread(final LoggingEventHandler handler) { super(handler, "gator-handler-log4j-" + handler.getRemoteAddress().getHostAddress()); this.loggingEventHandler = handler; } /** @return The handler executed by this thread. */ public LoggingEventHandler getLoggingEventHandler() { return loggingEventHandler; } /** {@inheritDoc}. */ @Override public void run() { try { super.run(); } catch (Exception e) { logger.error("Runnable threw unhandled exception", e); } finally { runningThreads.remove(this); } } } }