/**
* OpenSpotLight - Open Source IT Governance Platform
*
* Copyright (c) 2009, CARAVELATECH CONSULTORIA E TECNOLOGIA EM INFORMATICA LTDA
* or third-party contributors as indicated by the @author tags or express
* copyright attribution statements applied by the authors. All third-party
* contributions are distributed under license by CARAVELATECH CONSULTORIA E
* TECNOLOGIA EM INFORMATICA LTDA.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*
***********************************************************************
* OpenSpotLight - Plataforma de Governança de TI de Código Aberto
*
* Direitos Autorais Reservados (c) 2009, CARAVELATECH CONSULTORIA E TECNOLOGIA
* EM INFORMATICA LTDA ou como contribuidores terceiros indicados pela etiqueta
* @author ou por expressa atribuição de direito autoral declarada e atribuída pelo autor.
* Todas as contribuições de terceiros estão distribuídas sob licença da
* CARAVELATECH CONSULTORIA E TECNOLOGIA EM INFORMATICA LTDA.
*
* Este programa é software livre; você pode redistribuí-lo e/ou modificá-lo sob os
* termos da Licença Pública Geral Menor do GNU conforme publicada pela Free Software
* Foundation.
*
* Este programa é distribuído na expectativa de que seja útil, porém, SEM NENHUMA
* GARANTIA; nem mesmo a garantia implícita de COMERCIABILIDADE OU ADEQUAÇÃO A UMA
* FINALIDADE ESPECÍFICA. Consulte a Licença Pública Geral Menor do GNU para mais detalhes.
*
* Você deve ter recebido uma cópia da Licença Pública Geral Menor do GNU junto com este
* programa; se não, escreva para:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.openspotlight.common.concurrent;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import com.sun.source.util.TaskEvent;
/**
* The Class GossipExecutor has this name because it stay telling every listener what is going on ;-).
*/
public class GossipExecutor extends ThreadPoolExecutor {
/**
* A factory for creating DelegateThread objects.
*/
private static class DelegateThreadFactory implements ThreadFactory {
/** The listeners. */
private final CopyOnWriteArrayList<ThreadListener> listeners = new CopyOnWriteArrayList<ThreadListener>();
private final String poolName;
/** The wrapped. */
private final ThreadFactory wrapped;
/**
* Instantiates a new delegate thread factory.
*
* @param wrapped the wrapped
*/
public DelegateThreadFactory(
final ThreadFactory wrapped, final String poolName) {
this.wrapped = wrapped;
this.poolName = poolName;
}
/**
* Adds the thread listener.
*
* @param l the l
*/
public void addThreadListener(final ThreadListener l) {
listeners.add(l);
}
/*
* (non-Javadoc)
* @see java.util.concurrent.ThreadFactory#newThread(java.lang.Runnable)
*/
@Override
public Thread newThread(final Runnable r) {
final Thread t = wrapped.newThread(r);
t.setDaemon(true);
t.setName(poolName + "_" + t.getName());
for (final ThreadListener l: listeners) {
l.afterCreatingThread(t);
}
return t;
}
/**
* Removes the thread listener.
*
* @param l the l
*/
public void removeThreadListener(final ThreadListener l) {
listeners.remove(l);
}
}
/**
* The listener interface for receiving task events. The class that is interested in processing a task event implements this
* interface, and the object created with that class is registered with a component using the component's
* <code>addTaskListener<code> method. When
* the task event occurs, that object's appropriate
* method is invoked.
*
* @see TaskEvent
*/
public static interface TaskListener {
/**
* After executing task.
*
* @param r the r
* @param t the t
*/
public void afterExecutingTask(Runnable r,
Throwable t);
/**
* Before executing task.
*
* @param t the t
* @param r the r
*/
public void beforeExecutingTask(Thread t,
Runnable r);
}
/**
* The listener interface for receiving thread events. The class that is interested in processing a thread event implements
* this interface, and the object created with that class is registered with a component using the component's
* <code>addThreadListener<code> method. When
* the thread event occurs, that object's appropriate
* method is invoked.
*
* @see ThreadEvent
*/
public static interface ThreadListener {
/**
* After creating thread.
*
* @param t the t
*/
public void afterCreatingThread(Thread t);
}
/** The delegate thread factory. */
private final DelegateThreadFactory delegateThreadFactory;
/** The listeners. */
private final CopyOnWriteArrayList<TaskListener> listeners = new CopyOnWriteArrayList<TaskListener>();
/**
* Instantiates a new cautious executor.
*
* @param corePoolSize the core pool size
* @param maximumPoolSize the maximum pool size
* @param keepAliveTime the keep alive time
* @param unit the unit
* @param workQueue the work queue
*/
private GossipExecutor(
final int corePoolSize, final int maximumPoolSize, final long keepAliveTime, final TimeUnit unit,
final BlockingQueue<Runnable> workQueue, final String poolName) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
delegateThreadFactory = new DelegateThreadFactory(getThreadFactory(), poolName);
setThreadFactory(delegateThreadFactory);
}
/**
* New fixed thread pool.
*
* @param nThreads the n threads
* @return the cautious executor
*/
public static GossipExecutor newFixedThreadPool(final int nThreads,
final String poolName) {
final GossipExecutor ex = new GossipExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(), poolName);
return ex;
}
/*
* (non-Javadoc)
* @see java.util.concurrent.ThreadPoolExecutor#afterExecute(java.lang.Runnable, java.lang.Throwable)
*/
@Override
protected void afterExecute(final Runnable r,
final Throwable t) {
for (final TaskListener l: listeners) {
l.afterExecutingTask(r, t);
}
super.afterExecute(r, t);
}
/*
* (non-Javadoc)
* @see java.util.concurrent.ThreadPoolExecutor#beforeExecute(java.lang.Thread, java.lang.Runnable)
*/
@Override
protected void beforeExecute(final Thread t,
final Runnable r) {
for (final TaskListener l: listeners) {
l.beforeExecutingTask(t, r);
}
}
/**
* Adds the task listener.
*
* @param l the l
*/
public void addTaskListener(final TaskListener l) {
listeners.add(l);
}
/**
* Adds the thread listener.
*
* @param l the l
*/
public void addThreadListener(final ThreadListener l) {
delegateThreadFactory.addThreadListener(l);
}
/**
* Removes the task listener.
*
* @param l the l
*/
public void removeTaskListener(final TaskListener l) {
listeners.remove(l);
}
/**
* Removes the thread listener.
*
* @param l the l
*/
public void removeThreadListener(final ThreadListener l) {
delegateThreadFactory.removeThreadListener(l);
}
}