让非Spring人士的生活变得轻松一些
我们的软件倾向于使用大量线程池-主要是通过java.util.concurrent.ExecutorService
实现(通过创建Executors.new...
。我们为各种异步用例创建线程池,并且可以在各处看到它们。所有这些执行器都有线程工厂。它隐藏在默认的工厂方法,但您可以提供线程工厂;如果未提供,则在需要线程时使用默认的线程工厂。
使用Spring时,可以使用来创建<task:executor />
。在这种情况下,每个执行程序服务的线程工厂都由Spring提供,并且使用执行程序bean的名称(用指定id="executorName"
)。但是对于不是由Spring创建的线程,将使用默认名称,这没有帮助,也不允许您按名称区分线程。
而且,您需要按名称区分线程–如果遇到性能问题,您可以研究各种选项:线程转储和使用top命令。在这两种情况下,知道执行线程服务的函数都是有用的,因为转储中的stacktrace可能并不总是显示出来的。
我最喜欢的快速调查工具是top
。更确切地说,top -H -p <pid>
。这显示了通常的顶部表,但是-H标志意味着应该打印用于所选进程的线程。按名称,您基本上可以获得最多的CPU繁忙且当前处于活动状态的线程。在这些情况下,拥有自定义名称非常有用。
但是,您如何设置名称?通过在创建每个执行程序时指定一个命名线程工厂。这是一个StackOverflow答案,其中提供了多种实现线程命名的方法。
我使用的方法基于第二个答案:
public class AsyncUtils { public static ThreadFactory createNamedThreadFactory(String name) { return new ThreadFactoryBuilder().setNameFormat(name + "-%d").build(); } }
通过Spring集中管理所有执行程序可能是一个更好的主意,但并不是每个人都在使用Spring,有时,甚至一小部分功能(甚至可能在Spring Beans之外)都需要执行程序。因此,最好是采用这种方法。