Java 自定义线程池的名称

一级抬杠运动员 2021-09-22 16:47:25 浏览数 (3130)
反馈

我们的软件倾向于使用大量的线程池——主要是通过​j​ava.util.concurrent.ExecutorService​​实现(通过​Executors.new...​创建)。我们为各种异步用例创建这些线程池,它们随处可见。所有这些执行器都有一个线程工厂。它隐藏在默认工厂方法,但您可以提供线程工厂。如果未提供,则在需要线程时使用默认线程工厂。

使用 spring 时,可以使用​<task:executor />​。在这种情况下,每个执行程序服务的线程工厂由 spring 提供,它使用执行程序 bean 的名称(用​id="executorName"​指定)。但是对于那些不是由 spring 创建的,使用默认名称是没有帮助的,并且不允许您按名称区分线程。

并且您需要按名称区分线程——如果出现性能问题,您有多种调查选项:线程转储和使用 top 命令。在这两种情况下,了解线程服务的函数是有用的,因为转储中的堆栈跟踪可能并不总是显示出来。

我最喜欢的快速调查工具是​top​,更准确地说,​top -H -p <pid>​。这显示了通常的顶部表,但 ​-H ​标志意味着应该打印所选进程的线程。按名称,您基本上会获得占用 CPU 最多且当前处于活动状态的线程。在这些情况下,自定义名称非常有用。

但是如何设置名称呢?通过在创建每个执行程序时指定一个命名的线程工厂。

我使用的方法基于第二个答案:

public class AsyncUtils {
    public static ThreadFactory createNamedThreadFactory(String name) {
        return new ThreadFactoryBuilder().setNameFormat(name + "-%d").build();
    }
}

通过 spring 集中管理所有 executor 可能是一个更好的主意,但并不是每个人都在使用 spring,有时甚至可能超出 spring bean 的一小部分功能需要一个 executor。因此,这是一个很好的方法。


0 人点赞