package org.apache.cassandra.concurrent;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;
import com.google.common.annotations.VisibleForTesting;
import io.netty.util.concurrent.FastThreadLocal;
import io.netty.util.concurrent.FastThreadLocalThread;
public class NamedThreadFactory implements ThreadFactory
{
private static volatile String globalPrefix;
public static void setGlobalPrefix(String prefix) { globalPrefix = prefix; }
public final String id;
private final int priority;
private final ClassLoader contextClassLoader;
private final ThreadGroup threadGroup;
protected final AtomicInteger n = new AtomicInteger(1);
public NamedThreadFactory(String id)
{
this(id, Thread.NORM_PRIORITY);
}
public NamedThreadFactory(String id, int priority)
{
this(id, priority, null, null);
}
public NamedThreadFactory(String id, int priority, ClassLoader contextClassLoader, ThreadGroup threadGroup)
{
this.id = id;
this.priority = priority;
this.contextClassLoader = contextClassLoader;
this.threadGroup = threadGroup;
}
public Thread newThread(Runnable runnable)
{
String name = id + ':' + n.getAndIncrement();
Thread thread = createThread(threadGroup, runnable, name, true);
thread.setPriority(priority);
if (contextClassLoader != null)
thread.setContextClassLoader(contextClassLoader);
return thread;
}
public static Runnable threadLocalDeallocator(Runnable r)
{
return () ->
{
try
{
r.run();
}
finally
{
FastThreadLocal.removeAll();
}
};
}
private static final AtomicInteger threadCounter = new AtomicInteger();
@VisibleForTesting
public static Thread createThread(Runnable runnable)
{
return createThread(null, runnable, "anonymous-" + threadCounter.incrementAndGet());
}
public static Thread createThread(Runnable runnable, String name)
{
return createThread(null, runnable, name);
}
public static Thread createThread(Runnable runnable, String name, boolean daemon)
{
return createThread(null, runnable, name, daemon);
}
public static Thread createThread(ThreadGroup threadGroup, Runnable runnable, String name)
{
return createThread(threadGroup, runnable, name, false);
}
public static Thread createThread(ThreadGroup threadGroup, Runnable runnable, String name, boolean daemon)
{
String prefix = globalPrefix;
Thread thread = new FastThreadLocalThread(threadGroup, threadLocalDeallocator(runnable), prefix != null ? prefix + name : name);
thread.setDaemon(daemon);
return thread;
}
}