1. 程式人生 > >自定義名稱的執行緒池

自定義名稱的執行緒池

我們來看一下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

輸出了自定義的執行緒池的名稱和執行緒池的序號,方便除錯和定位問題。