最近在看java多线程编程核心技术这本书,由于一直对于线程的应用和学习不深,在例子中碰到Thread.currentThread().getName() 和 this.getName()的问题很困惑,自我测试理解记录,有不对的地方还请多多指教。
public class CurrentThreadTest extends Thread {
public CurrentThreadTest(){
System.out.println("CurrentThreadTest构造函数开始");
System.out.println("Thread.currentThread().getName(): " + Thread.currentThread().getName());
System.out.println("this.getName():" + this.getName());
System.out.println(Thread.currentThread().getName() == this.getName());
System.out.println("CurrentThreadTest构造函数结束");
System.out.println("");
}
@Override
public void run(){
System.out.println("run方法开始");
System.out.println("Thread.currentThread().getName(): " + Thread.currentThread().getName());
System.out.println("this.getName():" + this.getName());
System.out.println(Thread.currentThread().getName() == this.getName());
System.out.println("run方法结束");
}
public static void main(String[] args) {
CurrentThreadTest ctt = new CurrentThreadTest();
ctt.setName("ctt");
ctt.start();
// Thread t = new Thread(ctt);
// t.setName("t");
// t.start();
}
}
添加了一个测试线程,运行的结果如下:
CurrentThreadTest构造函数开始
Thread.currentThread().getName(): main
this.getName():Thread-0
false
CurrentThreadTest构造函数结束
run方法开始
Thread.currentThread().getName(): ctt
this.getName():ctt
true
run方法结束
这里可以看出,当构造函数初始话的时候,由于是在main函数里面初始化的,这时候正在运行的线程是main线程,所以
Thread.currentThread().getName()的结果为main。而我们正在执行的操作是new CurrentThreadTest()这个操作,所以this对象是ctt,但这个时候,还没有给ctt线程命名,查看源码,发现默认赋值"Thread_"开头的名称,所以this.getName()显示为Thread-0
public Thread() {
init(null, null, "Thread-" + nextThreadNum(), 0);
}
ctt.setName("ctt")为ctt线程赋值为ctt这个名称。当ctt.start()时,,CurrentThreadTest 这个线程调用的run 方法,所以这个时候的Thread.currentThread().getName()的结果为ctt,这个时候执行的线程也是CurrentThreadTest里面的run方法,所以this.getName()的结果也为ctt。
当我们修改方法为
public static void main(String[] args) {
CurrentThreadTest ctt = new CurrentThreadTest();
ctt.setName("ctt");
//ctt.start();
Thread t = new Thread(ctt);
t.setName("t");
t.start();
}
运行结果为
CurrentThreadTest构造函数开始
Thread.currentThread().getName(): main
this.getName():Thread-0
false
CurrentThreadTest构造函数结束
run方法开始
Thread.currentThread().getName(): t
this.getName():ctt
false
run方法结束
构造函数和上边是一致的。这个的时候,吧ctt这个线程委托个t这个线程,这个时候,t.start()调用的时候,由t这个线程调用ctt线程里的run方法,所以这个时候Thread.currentThread().getName()的结果为t,由于当前执行任务的线程为ctt这个线程(也就是run方法所在的线程),所以this.getName()的值为ctt
源码为:
public Thread(Runnable target) {
init(null, target, "Thread-" + nextThreadNum(), 0);
}
private void init(ThreadGroup g, Runnable target, String name,
long stackSize, AccessControlContext acc) {
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; //这里吧target 赋值给私有变量
setPriority(priority);
if (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();
}
@Override
public void run() {
//当target 不为null时,调用的是传过来的线程的run方法
if (target != null) {
target.run();
}
}
个人理解:
Thread.currentThread().getName() 为调用run方法的那个线程,也就是运行start()的那个线程。
this.getName()为当前正在执行任务的这个线程
参考文章:https://blog.csdn.net/Tracycater/article/details/54288623, https://blog.csdn.net/yezis/article/details/57513130
多线程基础总结请参考:https://blog.csdn.net/mra__s__/article/details/58598438
本文通过实例解析了Java多线程编程中Thread.currentThread().getName()与this.getName()的区别,阐述了它们分别代表调用run方法的线程与当前执行任务线程的概念。

318

被折叠的 条评论
为什么被折叠?



