Thread
的构造器都是调用了init
方法,所以我们来看一下init
方法
private void init(ThreadGroup g,
Runnable target,
String name,
long stackSize,
AccessControlContext acc,
boolean inheritThreadLocals) {
// name字段不可为空,new Thread的时候会赋予“Thread-数字”的名字
if (name == null) {
throw new NullPointerException("name cannot be null");
}
this.name = name;
// 调用该方法的线程是新线程的parent
Thread parent = currentThread();
// System里的SecurityManager实例是静态代码块初始化的时候调用了一个native方法里创建的
SecurityManager security = System.getSecurityManager();
// 线程组
if (g == null) {
// 首先由security决定
if (security != null) {
g = security.getThreadGroup();
}
// 如果security为空或者没有给出明确的组,则使用父线程的组
if (g == null) {
g = parent.getThreadGroup();
}
}
/* checkAccess regardless of whether or not threadgroup is
explicitly passed in. */
// MODIFY_THREADGROUP_PERMISSION权限检查,之后要对组进行操作
g.checkAccess();
/*
* Do we have the required permissions?
*/
if (security != null) {
if (isCCLOverridden(getClass())) {
security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
}
}
// 线程组里面对未start的进程维护一个计数器
g.addUnstarted();
this.group = g;
this.daemon = parent.isDaemon();
this.priority = parent.getPriority();
// 类加载器private ClassLoader contextClassLoader;
if (security == null || isCCLOverridden(parent.getClass()))
this.contextClassLoader = parent.getContextClassLoader();
else
this.contextClassLoader = parent.contextClassLoader;
this.inheritedAccessControlContext =
acc != null ? acc : AccessController.getContext();
this.target = target;
setPriority(priority);
// 是否继承父线程的ThreadLocal
if (inheritThreadLocals && parent.inheritableThreadLocals != null)
this.inheritableThreadLocals =
ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
/* Stash the specified stack size in case the VM cares */
this.stackSize = stackSize;
/* Set thread ID */
tid = nextThreadID();
}
总结
- 配置线程组、target、name线程名、stackSize栈深、tid线程ID,priority优先级、是否是后台线程、parent父线程
- 线程组维护unstart计数器
- 配置类加载器CCL,配置inheritedAccessControlContext