自定义 ExecutorService 中线程的名称
1、概览
ExecutorService
在 Java 中提供了一种方便的方式来管理线程并执行并发任务。在使用 ExecutorService
时,为线程和线程池分配有意义的名称可以提高调试、监控和理解线程的效果。
本文将带你了解在 Java 的 ExecutorService
中为线程和线程池命名的不同方式。
2、设置线程的名称
如果不使用 ExecutorService
,可以在 Java 中通过 Thread#setName
方法轻松设置线程名。
ExecutorService
使用默认的线程池和线程名称,如 pool-1-thread-1
、pool-1-thread-2
等,但也可以为 ExecutorService
管理的线程指定自定义的线程名称。
首先,创建一个简单程序,执行 ExecuterService
,输出默认的线程和线程池名称:
ExecutorService executorService = Executors.newFixedThreadPool(3);
for (int i = 0; i < 5; i++) {
executorService.execute(() -> System.out.println(Thread.currentThread().getName()));
}
运行程序,输出如下:
pool-1-thread-1
pool-1-thread-2
pool-1-thread-1
pool-1-thread-3
pool-1-thread-2
2.1、使用自定义 ThreadFactory
在 ExecutorService
中,新线程是通过 ThreadFactory
创建的。ExecutorService
默认使用 Executors.defaultThreadFactory
创建线程来执行任务。
通过向 ExecuterService
提供不同的自定义 ThreadFactory
,我们可以更改线程的名称、优先级等。
首先,创建 ThreadFactory
的实现:MyThreadFactory
。然后,为 MyThreadFactory
创建的新线程设置自定义线程名称:
public class MyThreadFactory implements ThreadFactory {
private AtomicInteger threadNumber = new AtomicInteger(1);
private String threadlNamePrefix = "";
public MyThreadFactory(String threadlNamePrefix) {
this.threadlNamePrefix = threadlNamePrefix;
}
public Thread newThread(Runnable runnable) {
// 创建线程,设置自定义名称
return new Thread(runnable, threadlNamePrefix + threadNumber.getAndIncrement());
}
}
然后,其传递给 ExecutorService
:
MyThreadFactory myThreadFactory = new MyThreadFactory("MyCustomThread-");
ExecutorService executorService = Executors.newFixedThreadPool(3, myThreadFactory);
for (int i = 0; i < 5; i++) {
executorService.execute(() -> System.out.println(Thread.currentThread().getName()));
}
最后,执行程序,可以看到 ExecutorService
的线程打印出我们自定义的线程名称:
MyCustomThread-1
MyCustomThread-2
MyCustomThread-2
MyCustomThread-3
MyCustomThread-1
2.2、使用 Apache Commons 的 BasicThreadFactory
首先,将 commons-lang3 的依赖添加到项目中:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.14.0</version>
</dependency>
然后,用自定义线程名称创建 BasicThreadFactory
。最后,用自定义线程工厂创建 ExecutorService
:
BasicThreadFactory factory = new BasicThreadFactory.Builder()
.namingPattern("MyCustomThread-%d").priority(Thread.MAX_PRIORITY).build();
ExecutorService executorService = Executors.newFixedThreadPool(3, factory);
for (int i = 0; i < 5; i++) {
executorService.execute(() -> System.out.println(Thread.currentThread().getName()));
}
如上,通过 namingPattern()
方法设置了线程名称的命名模式。
最后,运行程序,打印出的自定义线程名称如下:
MyCustomThread-1
MyCustomThread-2
MyCustomThread-2
MyCustomThread-3
MyCustomThread-1
2.3、使用 Guava 的 ThreadFactoryBuilder
Guava 的 ThreadFactoryBuilder
也提供了创建自定义线程的选项。
首先,添加 guava 依赖:
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>33.2.0-jre</version>
</dependency>
然后,用自定义名称创建 ThreadFactory
,并将其传递给 ExecutorService
:
ThreadFactory namedThreadFactory = new ThreadFactoryBuilder()
.setNameFormat("MyCustomThread-%d").build();
ExecutorService executorService = Executors.newFixedThreadPool(3, namedThreadFactory);
for (int i = 0; i < 5; i++) {
executorService.execute(() -> System.out.println(Thread.currentThread().getName()));
}
如上,通过 setNameFormat()
方法设置了线程名称的名称模式。
最后,运行程序,打印出的自定义线程名称如下:
MyCustomThread-0
MyCustomThread-1
MyCustomThread-2
MyCustomThread-2
MyCustomThread-1
以上是在使用 Java 中的 ExecutorService
时可以命名线程的一些方法,这些方法可以根据应用的需求灵活地选择。
3、总结
本文介绍了给 Java ExecutorService
中线程和线程池设置自定义名称的不同方法。
首先介绍了默认的线程名称,然后介绍了如何使用自定义 ThreadFactory
以及 Apache Commons 和 Guava 等不同 API 的 ThreadFactory
实现来自定义线程的名称。
Ref:https://www.baeldung.com/java-naming-executor-service-thread