既然都使用的线程池,则创建线程的工作都交付给了线程池去完成。我们只需要告诉线程池需要多少个线程,剩下的工作都交于线程池完成。在线程池中创建线程使用的是线程工厂,
下面我们看看有哪些线程工厂:
ThreadFactory(父级接口)
public interface ThreadFactory {
// 构造一个新的Thread 。实现还可以初始化优先级、名称、守护进程状态、 ThreadGroup等
Thread newThread(Runnable r);
}
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();
// 线程名称前缀 = pool + 线程池号 + thread
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;
}
}
PrivilegedThreadFactory
// 特权线程工厂
// 线程工厂捕获访问控制上下文和类加载器
static class PrivilegedThreadFactory extends DefaultThreadFactory {
private final AccessControlContext acc;
private final ClassLoader ccl;
PrivilegedThreadFactory() {
super();
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
// Calls to getContextClassLoader from this class
// never trigger a security check, but we check
// whether our callers have this permission anyways.
sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
// Fail fast
sm.checkPermission(new RuntimePermission("setContextClassLoader"));
}
this.acc = AccessController.getContext();
this.ccl = Thread.currentThread().getContextClassLoader();
}
public Thread newThread(final Runnable r) {
return super.newThread(new Runnable() {
public void run() {
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
Thread.currentThread().setContextClassLoader(ccl);
r.run();
return null;
}
}, acc);
}
});
}
}