java多線程中this與Thread.currentThread()返回值的引用問題

先看以下代碼:
public class Hello extends Thread {  
public Hello(){
System.out.println("Thread.currentThread().getname()="+Thread.currentThread().getName());
System.out.println("This.getName="+this.getName());
}
public void run(){
System.out.println("Thread.currentThread().getname()="+Thread.currentThread().getName());
System.out.println("This.getName="+this.getName());
}
public static void main(String[] args){
     hello t0 =new Hello();
     Thread t1 =new Thread(t0);
     t1.setName("A");
     t1.start();
  }
    }
得到結果
Thread.currentThread().getname()=main
This.getName=Thread-0
Thread.currentThread().getname()=A
This.getName=Thread-0


第一二三行輸出沒什麼異議。
在main線程中執行new Hello()的時候,實例化了一個Hello對象,此時正在執行的線程是main線程,故Thread.currentThread().getname()=main。
而this此時指向的是剛實例化出來的那個Hello對象,默認爲其分配的線程id是0,故this.getName()=Thread-0.
隨後利用new Thread(t0)實例化並以t0爲參數初始化了一個線程對象,t1引用了這個對象。
再然後t1.setName("A")將t1引用的線程命名爲"A"。
然後t1.start()將t1添加到默認線程組中去。
最後t1得到了執行的機會,t1.run()方法被調用,此時工作線程是t1,故Thread.currentThread().getName()="A"。
然後讓人困惑的是,爲什麼此時this.getName()語句被執行的時候返回的是"Thread-0"而非"A"。我們不是用t0去新建了一個線程麼?
根據輸出的結果來看,此時的this應當引用的還是最初創建的線程t0。
這是爲什麼呢?查看JDK源代碼:
發現以下一些情況:
#java.lang.Thread
public class Thread implements Runnable
{
/* What will be run. */
private Runnable target;
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) 
{
//other operations
this.target = target;
//......
}
public void run()
{
if(target != null) {
 target.run();
}
}
謎底揭開了,當使用一個Runnable對象(t0)爲參數去實例化一個Thread對象時,它僅僅是生成一個新的Thread對象(t1)。
並且,在這個對象中有一個私有實例域target,它將引用傳入的Runnable對象(t0)。
在t1.run()被調用時,t1將執行target.run(),即將會直接調用t0的run方法,如此一來,
target.run()方法中的Thread.currentThread()將返回和t1引用的相同對象,即"A"。
而target.run()方法中的this卻引用的是和target引用的對象也是t0引用的對象,即Thread-0.
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章