【线程池】java.util.concurrent.ThreadFactory作用

简介

ThreadFactory顾名思义,线程工厂接口,作用是构建一个线程,我们看下接口定义:

//JDK 1.8
public interface ThreadFactory {
    
    
  Thread newThread(Runnable r);
}

ThreadFactory接口仅有一个抽象方法,返回一个Thread 实例。

使用ThreadFactory

一般我们在创建线程池可以指定ThreadFactory,比如:

//JDK 1.8
public class ThreadPoolExecutor{
    
    
    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory)

在调用ThreadPoolExecutor时,我们也可以不传递ThreadFactory,内部会默认创建一个ThreadFactory的实例:

    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue){
    
    
   this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), defaultHandler);                           
   }                           

如上面的源码显示,通过Executors.defaultThreadFactory()传入默认的ThreadFactory ,我们看下这个默认的实现:

 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-" +
                        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 无参构造函数生成了线程名称前缀,在创建线程实例时,拼接该线程名称

自定义ThreadFactory

既然可以不指定ThreadFactory,为何要自定义呢?

最重要的一个作用就是设置线程名称,多线程调试起来本来就费劲,如果没有标识符,那就更难了。所以这个功能还是很重要的,并且也是编码规范中推荐的。

示例

MyThreadFactory基本拷贝自DefaultThreadFactory ,我们只是在构造函数传入一个自定义的线程名称前缀:

public class MyThreadFactory 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;

    public MyThreadFactory(String threadName) {
    
       //带入参的构造函数
        SecurityManager s = System.getSecurityManager();
        group = (s != null) ? s.getThreadGroup() :
                              Thread.currentThread().getThreadGroup();
        namePrefix = "pool-" + threadName +    //拼接自定义的线程前缀
                      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;
    }
}

猜你喜欢

转载自blog.csdn.net/m0_45406092/article/details/108576406