自定義名稱的執行緒池
阿新 • • 發佈:2018-12-19
我們來看一下JDK1.6中java.util.concurrent.Executors使用的DefaultThreadFactory:
/**
* The default thread factory
*/
static class DefaultThreadFactory implements ThreadFactory {
static final AtomicInteger poolNumber = new AtomicInteger(1);
final ThreadGroup group;
final AtomicInteger threadNumber = new AtomicInteger(1);
final String namePrefix;
DefaultThreadFactory() {
SecurityManager s = System.getSecurityManager();
group = (s != null)? s.getThreadGroup() :
Thread.currentThread().getThreadGroup();
namePrefix = "pool-" +
poolNumber.getAndIncrement() +
"-thread-";
}
public Thread newThread(Runnable r) {
Thread t = new Thread(group, r,
namePrefix + threadNumber.getAndIncrement(),
0 );
if (t.isDaemon())
t.setDaemon(false);
if (t.getPriority() != Thread.NORM_PRIORITY)
t.setPriority(Thread.NORM_PRIORITY);
return t;
}
}
設定一個更有意義的執行緒名.
在DefaultThreadFactory中建立的執行緒名字格式為pool-m-thread-n, 也就是pool-1-thread-2,pool-2-thread-3,完全看不出該執行緒為何建立,在做什麼事情。在除錯、監控和檢視日誌時非常不便。
尤其是在分析thread dump時,執行緒名是確認執行緒由哪個Executor或thread pool建立和了解執行緒資訊的重要線索。 在stack trace中,往往從頭到尾都是JDK的類,很難知道這個執行緒是做什麼的。一個有意義的執行緒名可以幫助我們迅速地定位問題。那麼我們就自己嘗試寫一個帶有名稱的執行緒工廠吧:
class MssThreadFactory implements ThreadFactory {
private final AtomicInteger threadNumber = new AtomicInteger(1);
private final String namePrefix;
MssThreadFactory(String namePrefix) {
this.namePrefix = namePrefix+"-";
}
public Thread newThread(Runnable r) {
Thread t = new Thread( r,namePrefix + threadNumber.getAndIncrement());
if (t.isDaemon())
t.setDaemon(true);
if (t.getPriority() != Thread.NORM_PRIORITY)
t.setPriority(Thread.NORM_PRIORITY);
return t;
}
}
使用時:
ThreadPoolExecutor pool = new ThreadPoolExecutor(10, 10, 0, TimeUnit.MINUTES, new LinkedBlockingQueue<>(),new MssThreadFactory("我的專屬執行緒池"));
for (int i = 0; i < 100; i++) {
final int index = i;
pool.submit(() -> System.out.println(Thread.currentThread().getName()));
}
輸出的結果:
我的專屬執行緒池-3
我的專屬執行緒池-1
我的專屬執行緒池-3
我的專屬執行緒池-4
我的專屬執行緒池-7
我的專屬執行緒池-6
我的專屬執行緒池-5
我的專屬執行緒池-2
我的專屬執行緒池-4
我的專屬執行緒池-3
我的專屬執行緒池-1
我的專屬執行緒池-9
我的專屬執行緒池-8
我的專屬執行緒池-10
輸出了自定義的執行緒池的名稱和執行緒池的序號,方便除錯和定位問題。