自定义名称的线程池

我们来看一下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

输出了自定义的线程池的名称和线程池的序号,方便调试和定位问题。

猜你喜欢

转载自blog.csdn.net/xqnode/article/details/80205342