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

时间:2014-10-12 06:57:50

标签: java multithreading synchronized

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

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

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

请解释为什么会这样。

1 个答案:

答案 0 :(得分:4)

因为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是第一个线程。