getName() vs Thread.currentThread().getName().请解释这两者之间的区别


public class SynchThread1 extends Thread {
    SynchThread1 st;
    SynchThread1() {}
    SynchThread1(SynchThread1 s) {
        st = s;
    }
    public void run() {
        st.show();
    }
    synchronized void show() {
        for (int i = 0; i < 5; i++)
            System.out.print(Thread.currentThread().getName() + " "); //replace here
    }
    public static void main(String[] args) {
        SynchThread1 s1 = new SynchThread1();
        Thread t1 = new SynchThread1(s1);
        Thread t2 = new SynchThread1(s1);
        Thread t3 = new SynchThread1(s1);
        s1.setName("t0");
        t1.setName("t1");
        t2.setName("t2");
        t3.setName("t3");
        t1.start();
        t2.start();
        t3.start();
    }
}

上述代码的输出为:

t1 t1 t1 t1 t1 t3 t3 t3 t3 t3 t2 t2 t2 t2 t2

但是如果我仅用getName()替换Thread.currentThread().getName(),则输出为:

t0 t0 t0 t0 t0 t0 t0 t0 t0 t0 t0 t0 t0 t0 t0

请解释为什么会发生这种情况。

因为Thread.currentThread().getName()会获取当前正在运行的线程的名称,但getName()解析为 st.getName() ,并且st始终是您的第一个线程实例。

为什么getName()决心st.getName()?因为:

  1. 在构造第二个到第四个线程期间,将第一个线程作为参数传入,并将其保存在实例成员st中。

  2. 线程的run方法调用st.show(),因此它们始终在第一个线程上调用show。(如果你曾经启动过第一个线程,你会在那里得到一个 NPE,因为第一个线程的st成员永远不会被赋予非null值。

  3. show内,this因此st(第一个线程(。非限定实例方法调用使用 this 作为其实例,this 是第一个线程。

相关内容

最新更新