package de.invesdwin.util.concurrent;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;
import javax.annotation.concurrent.ThreadSafe;
import de.invesdwin.util.assertions.Assertions;
@ThreadSafe
public class WrappedThreadFactory implements ThreadFactory {
public static final AtomicInteger THREADPOOL_IDS = new AtomicInteger();
private final int threadpoolId = THREADPOOL_IDS.incrementAndGet();
private final AtomicInteger threadIds = new AtomicInteger();
private final String name;
private final ThreadFactory delegate;
public WrappedThreadFactory(final String name, final ThreadFactory delegate) {
Assertions.assertThat(name).isNotNull();
Assertions.assertThat(delegate).isNotNull();
this.name = name;
this.delegate = delegate;
Assertions.assertThat(delegate).isNotInstanceOf(WrappedThreadFactory.class);
}
@Override
public Thread newThread(final Runnable r) {
final Thread t = delegate.newThread(r);
final String parentThreadName = Thread.currentThread().getName();
final String curThreadName = threadpoolId + "-" + threadIds.incrementAndGet() + ":" + name;
t.setName(curThreadName + Threads.NESTED_THREAD_NAME_SEPARATOR + parentThreadName);
/*
* So that exceptions are still logged if runnables are sent into executors without futures being checked. This
* keeps the default behaviour expected from normal threads.
*/
t.setUncaughtExceptionHandler(Thread.getDefaultUncaughtExceptionHandler());
return t;
}
public ThreadFactory getWrappedInstance() {
return delegate;
}
}