简介
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;
}
}