今天在看netty源码的时候,在netty创建NioEventLoopGroup的时候最后会用到这个类,所以就顺便学习一下这个类。
首先看到这个类不得不想起设计模式中的工厂设计模式:
工厂模式是最常用的模式之一,它可以把对象创建工作集中化,好处大家都知道:改变对象的创建方式将会变得很容易,而且可以控制创建对象的数量。
-ThreadFactory源码:
package java.util.concurrent;
/**
* An object that creates new threads on demand. Using thread factories
* removes hardwiring of calls to {@link Thread#Thread(Runnable) new Thread},
* enabling applications to use special thread subclasses, priorities, etc.
*
* <p>
* The simplest implementation of this interface is just:
* <pre> {@code
* class SimpleThreadFactory implements ThreadFactory {
* public Thread newThread(Runnable r) {
* return new Thread(r);
* }
* }}</pre>
*
* The {@link Executors#defaultThreadFactory} method provides a more
* useful simple implementation, that sets the created thread context
* to known values before returning it.
* @since 1.5
* @author Doug Lea
*/
public interface ThreadFactory {
/**
* Constructs a new {@code Thread}. Implementations may also initialize
* priority, name, daemon status, {@code ThreadGroup}, etc.
*
* @param r a runnable to be executed by new thread instance
* @return constructed thread, or {@code null} if the request to
* create a thread is rejected
*/
Thread newThread(Runnable r);
}
-
ThreadFactory(线程工厂接口)
在创建线程的时候,我们当然也能使用工厂模式来生产线程,ThreadFactory是用来实现创建线程的工厂接口,其实它只有一个方法Thread newThread(Runnable r),所以这个接口没多大用,可以自己编写新接口。
使用ThreadFactory工厂能替代默认的new Thread,而且在自定义工厂里面,我们能创建自定义化的Thread,并且计数,或则限制创建Thread的数量,给每个Thread设置对应的好听的名字,或则其他的很多很多事情。 -
线程工厂在java并发当中的使用
在Java中使用ThreadFactory最多应该就是Executor框架和Fork/Join框架了,使用ThreadFactory创建各种线程池中的线程。在Executor框架中,使用Executors创建线程池执行器的时候,也可以传入ThreadFactory对象,执行器将会使用该ThreadFactory对象来创建线程。 在netty中这个类被使用于executor当中。 -
使用实例
这里举的例子来自于netty:
public class DefaultThreadFactory implements ThreadFactory {
private static final AtomicInteger poolId = new AtomicInteger();
private final AtomicInteger nextId = new AtomicInteger();
private final String prefix;
private final boolean daemon;
private final int priority;
//ThreadGroup代表了一个线程的集合
protected final ThreadGroup threadGroup;
public DefaultThreadFactory(Class<?> poolType) {
//第三个是线程的优先级 false表示不是后台执行的
this(poolType, false, Thread.NORM_PRIORITY);
}
public DefaultThreadFactory(String poolName) {
this(poolName, false, Thread.NORM_PRIORITY);
}
public DefaultThreadFactory(Class<?> poolType, boolean daemon) {
this(poolType, daemon, Thread.NORM_PRIORITY);
}
public DefaultThreadFactory(String poolName, boolean daemon) {
this(poolName, daemon, Thread.NORM_PRIORITY);
}
public DefaultThreadFactory(Class<?> poolType, int priority) {
this(poolType, false, priority);
}
public DefaultThreadFactory(String poolName, int priority) {
this(poolName, false, priority);
}
public DefaultThreadFactory(Class<?> poolType, boolean daemon, int priority) {
this(toPoolName(poolType), daemon, priority);
}
/**
* 将传入的类的名字进行处理之后就得到了poolname
* 这个方法是在指定线程池的名字吧,如果不指定的话那么就会按照Thread默认的命名规则来了。
* @param poolType
* @return
*/
public static String toPoolName(Class<?> poolType) {
if (poolType == null) {
throw new NullPointerException("poolType");
}
String poolName = StringUtil.simpleClassName(poolType);
switch (poolName.length()) {
case 0:
return "unknown";
case 1:
return poolName.toLowerCase(Locale.US);
default:
if (Character.isUpperCase(poolName.charAt(0)) && Character.isLowerCase(poolName.charAt(1))) {
return Character.toLowerCase(poolName.charAt(0)) + poolName.substring(1);
} else {
return poolName;
}
}
}
public DefaultThreadFactory(String poolName, boolean daemon, int priority, ThreadGroup threadGroup) {
if (poolName == null) {
throw new NullPointerException("poolName");
}
if (priority < Thread.MIN_PRIORITY || priority > Thread.MAX_PRIORITY) {
throw new IllegalArgumentException(
"priority: " + priority + " (expected: Thread.MIN_PRIORITY <= priority <= Thread.MAX_PRIORITY)");
}
prefix = poolName + '-' + poolId.incrementAndGet() + '-';
this.daemon = daemon;
this.priority = priority;
this.threadGroup = threadGroup;
}
public DefaultThreadFactory(String poolName, boolean daemon, int priority) {
//System.getSecurityManager()返回java的安全管理器,如果有的话使用它所在的线程组,否则使用当前线程的线程组
this(poolName, daemon, priority, System.getSecurityManager() == null ?
Thread.currentThread().getThreadGroup() : System.getSecurityManager().getThreadGroup());
}
@Override
public Thread newThread(Runnable r) {
Thread t = newThread(FastThreadLocalRunnable.wrap(r), prefix + nextId.incrementAndGet());
try {
if (t.isDaemon() != daemon) {
t.setDaemon(daemon);
}
if (t.getPriority() != priority) {
t.setPriority(priority);
}
} catch (Exception ignored) {
// Doesn't matter even if failed to set.
}
return t;
}
protected Thread newThread(Runnable r, String name) {
return new FastThreadLocalThread(threadGroup, r, name);
}
}