1、线程的默认命名
2、命名线程
3、修改线程的名字
4、线程的父子关系
在构造线程的时候可以为线程起一个有意义的名字,这也是比较好的一种做法,尤其在一个线程比较多的程序中,为线程赋予一个包含特殊意义的名字有助于问题的排查和线程的跟踪,因此笔者强烈推荐在构造线程的时候赋予他一个名字
--------------------------------------------------------线程的默认命名-------------------------------------------------------------------
Thread()
Thread(Runnable targets)
Thread(ThreadGroup group,Runnable targets)
会有一个默认的自增命名方式
Thread-0
Thread-1
……
--------------------------------------------------------命名线程----------------------------------------------------------------------------
Thread(Runnable targets,String name)
Thread(String name)
Thread(ThreadGroup group,Runnable targets,String name)
Thread(ThreadGroup group,Runnable targets,String name,long stactkSize)
Thread(ThreadGroup group,String name)
可以在new线程的时候 对线程进命名操作
--------------------------------------------------------修改线程的名字------------------------------------------------------------------
线程启动之前可以对其重命名 setName
但是在线程启动之后就不能进行重命名了
--------------------------------------------------------线程的父子关系------------------------------------------------------------------
Thread的所有的构造函数,最终都会去调用一个静态方法init,我们截取init实现代码对其进行分析,不难发现创建的任何一线线程都会有一个父线程: Thread parent = currentThread();//获取当前线程为父线程
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) {
/* Determine if it's an applet or not */
/* If there is a security manager, ask the security manager
what to do. */
if (security != null) {
g = security.getThreadGroup();
}
/* If the security doesn't have a strong opinion of the matter
use the parent thread group. */
if (g == null) {
g = parent.getThreadGroup();
}
}
/* checkAccess regardless of whether or not threadgroup is
explicitly passed in. */
g.checkAccess();
/*
* Do we have the required permissions?
*/
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();
this.target = target;
setPriority(priority);
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();
}
上面代码中 Thread parent = currentThread();//获取当前线程为父线程
是获取当前线程,在线程生命周期中,我们说过线程的最初状态为new,没有执行start方法之前,他只能算是一个Thread的实例,并不意味着一个新的线程被创建,因此 currentThread()
代表的将会是创建它那个线程,因此我们可以得出一下结论。
- 一个线程的创建肯定是由另外一个线程完成的
- 被创建线程的府县丞是创建他的线程
我们知道mian函数所在的线程是由jvm创建的,也就是main线程,那就意味着我们之前创建所有的线程都是main线程的子线程。(其父线程是main线程)