【问题标题】:Thread and ThreadFactory线程和线程工厂
【发布时间】:2026-01-01 05:55:01
【问题描述】:

我只是对 Threads 和 ThreadFactory 有点困惑。所以我提出这个问题。 我的目的是为每个正在运行的线程设置一个名称,以便我可以轻松地在日志中跟踪哪个线程正在运行和中断。使用 ThreadFactory 我看到它是可能的。

String someName="fileName"; // Inside first file 
...........................
.........................

Executors.newFixedThreadPool(30, new ThreadFactoryBuilder().setNameFormat(someName).build()); //in singleton class

当线程开始执行某些任务时,我正在使用Thread.currentThread().getName() 获取当前正在进行的线程名称,这正在获取我作为 someName 的值。我的问题是,因为我在 newFixedThreadPool 中命名为 someName ,所以这个池中的所有线程都将保持相同的名称。如果我再次调用ExecutorService(这是单例类)并分配someName="fileName2"会发生什么

【问题讨论】:

  • 这篇文章会对你有所帮助。 ThreadFactory usage in Java
  • 您想知道 ThreadFactoryBuilder 是如何工作的,但它不是内置类。我假设你的意思是那个名字的番石榴类?这个类的来源说它做了什么?

标签: java multithreading singleton threadpool executorservice


【解决方案1】:

假设您正在谈论 Guava 类 ThreadFactoryBuilder setNameFormat 方法记录为

nameFormat - 一个与 String.format(String, Object...) 兼容的格式字符串,唯一的整数(0、1 等)将作为单个参数提供给该字符串。该整数对于已构建的 ThreadFactory 实例是唯一的,并将按顺序分配。

这意味着您必须在格式名称中包含您希望包含计数器的位置。如果您还没有这样做,那么您实际上已经声明您希望所有线程具有相同的名称。

我的问题是,由于我在 newFixedThreadPool 中命名为 someName ,因此该池中的所有线程都将保持相同的名称。

我的猜测是格式设置不正确,因此您的所有线程都将具有相同的名称。

如果我再次调用 ExecutorService(这是在单例类中)并分配 someName="fileName2" 会发生什么

新的线程池将拥有它的所有线程,称为“fileName2”

显然,您不想重复创建线程池。线程池的全部意义在于它是可重用的。

此外,您可能不希望线程池大小为 30。您更可能希望它是 CPU 的数量,或者根据您的使用情况加倍。

【讨论】:

  • 在这种情况下,您能告诉我如何格式化单个池中单个线程的名称吗?我不想每次都创建一个新池。这是通过将 ExecutorService 设为静态变量来实现的。但是,如果我想为单个线程分配任务并为其命名,我该怎么做。我已经使用 Thread.currentThread().setName() 和 getName 来了解正在运行的线程。有没有其他方法可以做到。
  • @Rashmi 我会使用 setName 并在完成后重置它。