环境:jdk1.8
对Thread的构造器进行预分析,发现Thread类的构造器中都调用了init初始化方法,所以先分析一下init方法:
1.首先看下最核心的init方法:
代码如下:
/**
* 初始化线程
* @param g 所属线程组
* @param target 运行实例
* @param name 线程名称
* @param stackSize 线程栈大小
* @param acc 接入控制器
* @param inheritThreadLocals 是否可以继承当前线程的inheritableThreadLocals属性
*/
private void init(ThreadGroup g, Runnable target, String name,
long stackSize, AccessControlContext acc,
boolean inheritThreadLocals)
{
//判断线程名称是否为null
if (name == null)
{
throw new NullPointerException("name cannot be null");
}
this.name = name;
//当前执行创建线程实例操作的线程
Thread parent = currentThread();
//获取系统安全服务
SecurityManager security = System.getSecurityManager();
//判断线程组是否为null
if (g == null)
{
//如果为null则通过安全服务获取线程组
if (security != null)
{
g = security.getThreadGroup();
}
//如果获取后的线程组仍为null,则获取当前线程的线程组
if (g == null)
{
g = parent.getThreadGroup();
}
}
//检查线程组(无论是否显式传入threadgroup)
//主要检查:1.是否线程组为null 2.是否根线程组,如果是则要检查其是否有修改权限
g.checkAccess();
//权限检查:子类不能覆盖对安全性敏感的方法,否则将检查“enableContextClassLoaderOverride”运行时权限
if (security != null)
{
if (isCCLOverridden(getClass()))
{
security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
}
}
//增加线程组中未启动线程的数量
g.addUnstarted();
this.group = g;
//将当前线程是否是守护线程的属性赋予新创建的线程
this.daemon = parent.isDaemon();
//将当前线程的执行优化级的属性赋予新创建的线程
this.priority = parent.getPriority();
//将当前线程的上下文类加载器的属性赋予新创建的线程
if (security == null || isCCLOverridden(parent.getClass()))
{
this.contextClassLoader = parent.getContextClassLoader();
}
else
{
this.contextClassLoader = parent.contextClassLoader;
}
//接入控制
this.inheritedAccessControlContext = acc != null ? acc : AccessController.getContext();
//Runnable实例
this.target = target;
//设置线程优先级
setPriority(priority);
//设置inheritableThreadLocals属性
if (inheritThreadLocals && parent.inheritableThreadLocals != null)
{
this.inheritableThreadLocals = ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
}
//设置栈大小
this.stackSize = stackSize;
//设置线程ID(加锁同步获取)
tid = nextThreadID();
}
Thread提供了八个构造器方法,因为内部都是调用了init初始化方法,所以我们不一一分析,只针对我们常用的一种构造器进行分析:
1.public Thread(Runnable target),传入Runnable实例
代码如下:
/**
* 线程实例构造器
* @param target Runnable实例
*/
public Thread(Runnable target)
{
//调用初始化方法,传入Runnable实例和线程名称
init(null, target, "Thread-" + nextThreadNum(), 0);
}
/**
* 对核心方法init进行了一层包装
* @param g 线程组
* @param target Runnable实例
* @param name 线程名称
* @param stackSize 栈大小
*/
private void init(ThreadGroup g, Runnable target, String name,long stackSize)
{
//调用核心初始化方法init
init(g, target, name, stackSize, null, true);
}
总结:
1.通过分析Thread的构造器,我们发现Thread支持灵活多变的参数初始化,这些属性为后面执行Thread的start、stop、interrupt、destroy、isAlive等方法提供了基础
2.构建新的线程时,会根据当前线程的一些属性决定新线程具有相同的属性,例如:线程优先级,默认继承当前线程;是否是守护线程,默认也是取决于当前线程