Java中Executor服務線程和線程池的命名
1. 概述
ExecutorService
提供了一種在 Java 中管理執行緒和執行並發任務的便捷方法。使用ExecutorService
時,為線程和線程池分配有意義的名稱對於改進線程的偵錯、監視和理解非常有用。在本文中,我們將了解 Java 的ExecutorService
中命名線程和線程池的不同方法。
首先,我們將了解如何在ExecutorService
中設定線程的預設名稱。然後,我們將看到使用自訂ThreadFactory, BasicThreadFactory
和 Guava 庫的ThreadFactoryBuilder
來自訂執行緒名稱的不同方法。
2. 命名線程
如果我們不使用ExecutorService.
雖然**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](https://download.java.net/java/early_access/jdk23/docs/api/java.base/java/util/concurrent/ThreadFactory.html) .
ExecutorService
使用Executors.defaultThreadFactory
建立其執行緒來執行任務。
透過向ExecuterService
提供不同的自訂ThreadFactory
,我們可以更改執行緒的名稱、優先權等。
首先,讓我們建立自己的MyThreadFactory
來實作ThreadFactory
。然後,我們將為使用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());
}
}
現在,我們將使用自訂工廠MyThreadFactory
來設定線程名稱並將其傳遞給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
中的BasicThreadFactory
實作了ThreadFactory
接口,該接口為執行緒提供配置選項,這有助於設定執行緒名稱。
首先,讓我們將[commons-lang3](https://mvnrepository.com/artifact/org.apache.commons/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
時命名線程的一些方法,可根據應用程式的要求提供靈活性。
三、結論
在本文中,我們了解了 Java 的ExecutorService
中命名線程和線程池的不同方法。
首先,我們了解如何設定預設名稱。後來,我們使用自訂的ThreadFactory
以及 Apache Commons 和 Guava 等不同 API 的ThreadFactory
來自訂執行緒名稱。
與往常一樣,本文的範例程式碼可在 GitHub 上取得。