Thread.currentThread().getName() 和 this.getName()区别详解

本文通过实例解析了Java多线程编程中Thread.currentThread().getName()与this.getName()的区别,阐述了它们分别代表调用run方法的线程与当前执行任务线程的概念。

最近在看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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值