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

一、代码:

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)