【线程池】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;
    }
}
ThreadPoolExecutor是Java中的一个线程池实现类,它可以管理和复用线程,从而提高程序的性能和效率。线程工厂是ThreadPoolExecutor的一个参数,用于创建新线程。如果不设置线程工厂,则默认使用Executors.defaultThreadFactory()方法创建线程。如果设置了线程工厂,则可以自定义线程的创建方式,例如设置线程的名称、优先级等。如果不设置线程工厂,线程的名称将会是“pool-x-thread-y”的形式,其中x是线程池的编号,y是线程的编号。 以下是设置线程工厂和不设置线程工厂的区别: 1. 设置线程工厂可以自定义线程的创建方式,例如设置线程的名称、优先级等。 2. 不设置线程工厂,线程的名称将会是“pool-x-thread-y”的形式,其中x是线程池的编号,y是线程的编号。 3. 如果不设置线程工厂,线程的优先级将会是默认值。 4. 如果设置了线程工厂,可以在创建线程时进行一些额外的操作,例如设置线程的UncaughtExceptionHandler。 下面是一个设置线程工厂的例子: ```java public class MyThreadFactory implements ThreadFactory { private final AtomicInteger threadNumber = new AtomicInteger(1); private final String namePrefix; public MyThreadFactory(String namePrefix) { this.namePrefix = namePrefix; } public Thread newThread(Runnable r) { Thread t = new Thread(r, namePrefix + threadNumber.getAndIncrement()); t.setPriority(Thread.NORM_PRIORITY); t.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { public void uncaughtException(Thread t, Throwable e) { System.out.println("Thread " + t.getName() + " threw an exception: " + e); } }); return t; } } ``` 在创建ThreadPoolExecutor时,可以将MyThreadFactory作为参数传入: ```java ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 20, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), new MyThreadFactory("my-thread-")); ``` 这样就可以自定义线程的名称和UncaughtExceptionHandler了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值