package org.jactr.core.concurrent;
/*
* default logging
*/
import java.util.WeakHashMap;
import java.util.concurrent.ThreadFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class GeneralThreadFactory implements ThreadFactory
{
/**
* Logger definition
*/
static private final transient Log LOGGER = LogFactory
.getLog(GeneralThreadFactory.class);
private int _count = 0;
private String _nameTemplate;
private ThreadGroup _group;
private WeakHashMap<Thread, Boolean> _membershipMap;
/**
* thread groups are currently disabled because in order to dispose of them
* correctly, all their threads need to have exited, however, the disposal
* will usually be called from one of those threads, hence it will always
* throw an exception.
*/
private boolean _useThreadGroups = false;
public GeneralThreadFactory(String nameTemplate)
{
this(nameTemplate, null);
}
public GeneralThreadFactory(String nameTemplate, ThreadGroup parentGroup)
{
_nameTemplate = nameTemplate;
if (_useThreadGroups) if (parentGroup != null)
_group = new ThreadGroup(parentGroup, _nameTemplate);
else
_group = new ThreadGroup(_nameTemplate);
_membershipMap = new WeakHashMap<Thread, Boolean>();
}
/**
* destroy the thread group, if any exists
*/
public void dispose()
{
if (_group != null)
try
{
_group.destroy();
_group = null;
}
catch (Exception e)
{
LOGGER.error(
"Could not destory thread group " + _group.getName() + " ", e);
}
}
public ThreadGroup getThreadGroup()
{
return _group;
}
public Thread newThread(final Runnable r)
{
Thread t = null;
Runnable defensive = new Runnable() {
public void run()
{
try
{
r.run();
}
catch (Throwable thrown)
{
LOGGER.error("Uncaught exception on "
+ Thread.currentThread().getName() + ", while executing "+r+"("+r.getClass().getName()+") : " + thrown.getMessage()
+ " ", thrown);
}
}
};
if (_group != null)
t = new Thread(_group, defensive);
else
t = new Thread(defensive);
t.setName(_nameTemplate + "-" + (++_count));
t.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
public void uncaughtException(Thread t, Throwable e)
{
LOGGER.error("Uncaught exception on " + t + " : ", e);
}
});
_membershipMap.put(t, Boolean.TRUE);
return t;
}
public boolean isMember(Thread thread)
{
return Boolean.TRUE.equals(_membershipMap.get(thread));
}
public boolean isMember()
{
return isMember(Thread.currentThread());
}
}