1. 程式人生 > >執行緒池---友好的執行緒池命名

執行緒池---友好的執行緒池命名

大家推薦個靠譜的公眾號程式設計師探索之路,大家一起加油,這個公眾號已經接入圖靈https://img-blog.csdnimg.cn/20181129224604602.png ​   

之前介紹過java 推薦的執行緒池和如何自定義執行緒池

https://mp.csdn.net/postedit/81783309

今天在使用執行緒池的時候發現執行緒池名字實在是太醜了

是這樣的

pool-1-thread-1 這樣不好看也沒有什麼意義,假如線上程裡的子執行緒執行出錯了檢視日誌的不能看出來哪個執行緒池,這樣就不是很友好。那麼怎麼給執行緒池裡的執行緒有意義的命名呢,咱們先了解一下java執行緒池預設名字是哪裡來的,我以

Executors.newCachedThreadPool()為例,其他的都是一樣的

發現都是呼叫Executors.defaultThreadFactory()方法,最終我們會走到Executors的靜態內部類DefaultThreadFactory實現的

static class DefaultThreadFactory implements ThreadFactory {
    private static final AtomicInteger poolNumber = new AtomicInteger(1);
    private final ThreadGroup group;
    private final AtomicInteger threadNumber = new AtomicInteger(1);
    private final String namePrefix;

    DefaultThreadFactory() {
        SecurityManager s = System.getSecurityManager();
        group = (s != null) ? s.getThreadGroup() :
                              Thread.currentThread().getThreadGroup();
       //namePrefix = pool- + 用當前工廠類建立的第幾個執行緒池 + -thread-
        namePrefix = "pool-" +
                      poolNumber.getAndIncrement() +
                     "-thread-";
    }

    public Thread newThread(Runnable r) {
       //這裡就是給執行緒命名的地方   namePrefix+當前執行緒池的第幾個執行緒
        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;
    }
}

至此我們明白了預設的執行緒名是如何命名的,那麼我們怎麼自定義的,很簡單我比葫蘆畫瓢就可以了

class NameTheadFactory implements ThreadFactory{
   private static final AtomicInteger poolNumber = new AtomicInteger(1);
   private final ThreadGroup group;
   private final AtomicInteger threadNumber = new AtomicInteger(1);
   private final String namePrefix;

   NameTheadFactory() {
      //預設namePrefix = default-name-pool
      this("default-name-pool");
   }

   NameTheadFactory(String name){
      SecurityManager s = System.getSecurityManager();
      group = (s != null) ? s.getThreadGroup() :
            Thread.currentThread().getThreadGroup();
//此時namePrefix就是 name + 第幾個用這個工廠建立執行緒池的
      this.namePrefix = name +
            poolNumber.getAndIncrement();
   }

   public Thread newThread(Runnable r) {
      //此時執行緒的名字 就是 namePrefix + -thread- + 這個執行緒池中第幾個執行的執行緒
      Thread t = new Thread(group, r,
            namePrefix + "-thread-"+threadNumber.getAndIncrement(),
            0);
      if (t.isDaemon())
         t.setDaemon(false);
      if (t.getPriority() != Thread.NORM_PRIORITY)
         t.setPriority(Thread.NORM_PRIORITY);
      return t;
   }
}

測試:

public static void main(String[] args) {
   final ThreadPoolExecutor zzhTestPool = new ThreadPoolExecutor(15, 60,
         5L, TimeUnit.MINUTES,
         new LinkedBlockingQueue<Runnable>(500), new NameTheadFactory("zzh-name-pool-"));
   for (int i = 0;i < 3;i++){
      zzhTestPool.execute(new Runnable() {
         @Override
         public void run() {
            System.out.println(Thread.currentThread().getName()+"||||----1");
         }
      });
   }
   final ThreadPoolExecutor zzhTestPool2 = new ThreadPoolExecutor(15, 60,
         5L, TimeUnit.MINUTES,
         new LinkedBlockingQueue<Runnable>(500), new NameTheadFactory());
   for (int i = 0;i < 3;i++) {
      zzhTestPool2.execute(new Runnable() {
         @Override
         public void run() {
            System.out.println(Thread.currentThread().getName() + "-->||||----1");
         }
      });
   }
   zzhTestPool.shutdown();
   zzhTestPool2.shutdown();
}

結果

zzh-name-pool-1-thread-2-->||||----1
zzh-name-pool-1-thread-3-->||||----1
zzh-name-pool-1-thread-1-->||||----1
pool2-thread-1-->||||----1
pool2-thread-2-->||||----1
pool2-thread-3-->||||----1