Thread作为线程的抽象,Thread的实例用于描述线程,对线程的操纵,就是对Thread实例对象的管理与控制。创建一个线程这个问题,也就转换为如何构造一个正确的Thread对象。
JDK1.7及之前Thread构造方法如下
注1 :jdk1.8.0_201版本下,新增了一个构造方法,但是该方法是非 public 的
一、构造方法核心
如前面两个图所示,Thread所有的构造方法都依赖于init 方法
private void init(ThreadGroup g, Runnable target, String name,long stackSize)
所以换一个角度思考,可以认为只有一个构造方法
这“唯一的一个构造方法”调用的是五个参数的 核心 init 方法。所以说,我们只需要关注底层的该init方法。
注 2:jdk1.8后核心init方法也由5参数变为了6参数
这是一种编码规范与设计思维---“构造方法中不设置初始化逻辑,如果需要,那么请将初始化逻辑进行封装”
对于Thread类来说,核心 init 方法,就是这个初始化逻辑的封装方法,所有的构造方法都依赖他。
这里只介绍参数中的部分,name 和 target 过于简单。
1.1 ThreadGroup g
ThreadGroup表示该线程所在的线程组,如果没有显式指定,那么底层调用init时,传递的参数为null,如果参数传递为null的话,ThreadGroup会有默认值的设置,如果有安全管理器,会请求管理器进行设置,如果安全管理器不存在或者根本就没有明确的指示,那么将会获取父线程的所在的线程组,父线程就是创建他的线程 Thread parent = currentThread();
所以,ThreadGroup是非必填项,如果不进行设置,会有默认初始值
1.2 long stackSize
每个线程都有私有的虚拟机栈,通过这个值可以设置栈空间的大小,Thread内部属性stackSize,设置的就是这个值。
堆栈大小是虚拟机要为该线程堆栈分配的地址空间的近似字节数,在某些平台上,指定一个较高的 stackSize 参数值可能使线程在抛出 StackOverflowError 之前达到较大的递归深度,如果指定一个较低的值将允许较多的线程并发地存在,且不会抛出 OutOfMemoryError(或其他内部错误)stackSize 参数(如果有)的作用具有高度的平台依赖性,某些平台这个值都可能被忽略如果这个值设置为0表示忽略设置。所以,对于stackSize可以进行设置,如果不设置默认是0,表示忽略该参数的设置,使用平台默认值。
1.3 AccessControlContext acc
注:该参数表示访问控制权限,了解 AccessControlContext 参考 Java安全模式 (暂不考虑)
在jdk1.7版本中,该参数在所有构造中都是不传的,会在init方法中有默认值。
而在1.8版本中,新增了一个构造方法,可以指定AccessControlContext ,为什么增加该方法以及如何使用暂不了解。
1.4 boolean inheritThreadLocals
注:该参数表示,是否从构造线程(父线程 Thread parent = currentThread())中继承线程局部变量的初始值
只有在这个jdk1.8新增的方法中,才会指定为false,一般默认为ture。
对于成员变量 ThreadLocal.ThreadLocalMap inheritableThreadLocals,表示的是与这个线程相关的InheritableThreadLocal值。这张地图是由InheritableThreadLocal类维护。
也就是说默认情况下(该参数为true),假如父线程使用InheritableThreadLocal维护了一个ThreadLocalMap inheritableThreadLocals,那么其子线程是可以继承map中的初始值的(InheritableThreadLocal 与 ThreadLocal 的介绍可以参考另一文章)
over~ 部分内容转载于https://www.cnblogs.com/noteless/p/10354753.html,推荐该文,非常详细。