private void init(ThreadGroup g, Runnable target, String name,
long stackSize, AccessControlContext acc,
boolean inheritThreadLocals) {
if (name == null) {
throw new NullPointerException("name cannot be null");
}
this.name = name;
// 获取当前线程
Thread parent = currentThread();
SecurityManager security = System.getSecurityManager();
if (g == null) {
if (security != null) {
g = security.getThreadGroup();
}
if (g == null) {
g = parent.getThreadGroup();
}
}
g.checkAccess();
if (security != null) {
if (isCCLOverridden(getClass())) {
security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
}
}
g.addUnstarted();
this.group = g;
......
}
Thread 的所有构造函数,最终都会去调用一个静态方法 init.
在线程生命周期中,线程的最初状态为 NEW,没有执行 start 方法之前,它只能算是一个 Thread 的实例,并不意味着一个新的线程被创建,因此 currentThread() 代表的将是创建它的那个线程,我们可以得出下面两个结论。
main 函数所在的线程是由 JVM 创建的,也就是 main 线程,那就意味着 main 线程创建的子线程,其父线程是 main 线程。
在 Thread 的构造函数中,可以显式地指定线程的 Group,也就是 ThreadGroup。
通过对源码分析,如果在构造 Thread 的时候没有显示指定一个 ThreadGroup,那么子线程线程组将被指定为父线程。
package concurrent;
public class ThreadConstruction {
public static void main(String[] args) {
// a 没有指定线程组
Thread t1 = new Thread("t1");
// b 创建一个测试线程组
ThreadGroup group = new ThreadGroup("TestGroup");
// c 构造函数中指定线程组
Thread t2 = new Thread(group, "t2");
// main 线程的线程组
ThreadGroup mainThreadGroup = Thread.currentThread().getThreadGroup();
System.out.println("main 线程的线程组:" + mainThreadGroup);
System.out.println("t1 线程的线程组:" + t1.getThreadGroup());
System.out.println("t2 线程的线程组:" + t2.getThreadGroup());
}
}
main 线程的线程组:java.lang.ThreadGroup[name=main,maxpri=10]
t1 线程的线程组:java.lang.ThreadGroup[name=main,maxpri=10]
t2 线程的线程组:java.lang.ThreadGroup[name=TestGroup,maxpri=10]
在默认设置中,除了子线程会和父线程同属于一个 Group 外,它还会和父线程拥有同样的优先级,同样的 daemon。
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/chengqiuming/article/details/122848518
内容来源于网络,如有侵权,请联系作者删除!