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

来源:互联网 发布:幕墙易云计算好用吗 编辑:程序博客网 时间:2024/06/05 20:53

一、代码:

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”).

新手写的,希望得到各种大牛不吝赐教。

0 0
原创粉丝点击