Thread源码-构造器及初始化

本文详细解析了Java中Thread类的构造器实现原理,重点分析了init方法如何初始化线程属性,包括线程组、线程名称、守护线程状态等,并介绍了线程属性的继承规则。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

环境: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.构建新的线程时,会根据当前线程的一些属性决定新线程具有相同的属性,例如:线程优先级,默认继承当前线程;是否是守护线程,默认也是取决于当前线程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值