您的位置:首页 > 编程语言 > Java开发

Java多线程中this.getName()和Thread.currentThread.getName()的区别?

2017-04-24 21:12 429 查看
一、代码:

public class CountOperate extends Thread {
public CountOperate(){
System.out.println("CountOperate---begin");
System.out.println("Thread.currentThread().getName() = " + Thread.currentThread().getName());
System.out.println("this.getName() = " + this.getName());
System.out.println("CountOperate---end");
}

@Override
public void run() {
// TODO Auto-generated method stub
super.run();
System.out.println("run---begin");
System.out.println("Thread.currentThread().getName() = " + Thread.currentThread().getName());
System.out.println("this.getName() = " + this.getName());
System.out.println("run---end");
}

public static void main(String[] args) {
CountOperate cp = new CountOperate();
Thread thread = new Thread(cp);
thread.setName("A");
thread.start();
}
}


二、控制台输出:

CountOperate—begin

Thread.currentThread().getName() = main

this.getName() = Thread-0

CountOperate—end

run—begin

Thread.currentThread().getName() = A

this.getName() = Thread-0

run—end

三、问题的抛出:

很奇怪,为什么控制台的输出结果不是两个main,两个A?

四、解答:

1、Thread类的部分代码:

public Thread(Runnable target) {
init(null, target, "Thread-" + nextThreadNum(), 0);
}

private void init(ThreadGroup g, Runnable target, String name,
long stackSize) {
init(g, target, name, stackSize, null);
}

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) {
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;
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 (parent.inheritableThreadLocals != null)
this.inheritableThreadLocals =
ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
this.stackSize = stackSize;
tid = nextThreadID();
}


通过继续查看Thread类的代码可以得知,其中还有两个全局变量:

private volatile String name;
private Runnable target;


2、上面的代码的意思就是,在main()方法中通过new Thread(cp)将继承了Thread类(即实现了Runnable接口)的CountOperate对象cp通过Thread类的构造方法,传给了Thread类的Runnable target属性;

这样的话我们在main()中通过start()开启线程的时候,而我们通过this.getName()得到的就是这个Runnable实例(即target)的name值(我们并没有赋值,而是使用系统默认的值);通过Thread.currentThread.getName()得到的才是当前线程的name值(因为后来我们通过thread.setName(“A”);这句代码将thread的name值重新赋值成了”A”).

新手写的,希望得到各种大牛不吝赐教。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java 多线程
相关文章推荐