private static ThreadFactory doBuild(ThreadFactoryBuilder builder) {
final String nameFormat = builder.nameFormat;
final Boolean daemon = builder.daemon;
final Integer priority = builder.priority;
final UncaughtExceptionHandler uncaughtExceptionHandler = builder.uncaughtExceptionHandler;
final ThreadFactory backingThreadFactory =
(builder.backingThreadFactory != null)
? builder.backingThreadFactory
: Executors.defaultThreadFactory();
final AtomicLong count = (nameFormat != null) ? new AtomicLong(0) : null;
return new ThreadFactory() {
@Override
public Thread newThread(Runnable runnable) {
Thread thread = backingThreadFactory.newThread(runnable);
if (nameFormat != null) {
thread.setName(format(nameFormat, count.getAndIncrement()));
}
if (daemon != null) {
thread.setDaemon(daemon);
}
if (priority != null) {
thread.setPriority(priority);
}
if (uncaughtExceptionHandler != null) {
thread.setUncaughtExceptionHandler(uncaughtExceptionHandler);
}
return thread;
}
};
}
最近我开始研究在线程池中创建新线程ThreadFactory
使用哪个。ThreadPoolExecutor
为了方便调试和监控,我们不希望线程池创建的线程是默认的0、1、2、3,而是取一个有意义的名字。
实现这一目标的一种方法是实现一个自定义ThreadLoad
的,可以在创建线程时设置线程的名称。Guava有一个方便的自定义构建器类ThreadFactory
,我希望从中学习。
理解这个类的大部分内容并不难,但我对方法count
中的变量感到很困惑。doBuild
我还去了实际调用的ThreadPoolExecutor#Worker
源代码newThread()
。ThreadFactory
Worker(Runnable firstTask) {
setState(-1); // inhibit interrupts until runWorker
this.firstTask = firstTask;
this.thread = getThreadFactory().newThread(this);
}
但我仍然不清楚为什么我们需要一个原子变量。
当然,我可以猜测线程池中的线程可能是以多线程方式创建的,因此为了确保线程的 id 不会重复,我们需要 id-generator 是一个原子变量,但我没有直接证据这个假设呢。
任何人都可以对此有所了解吗?