先看第一個例子:
public class MyThread extends Thread { public MyThread(){ System.out.println("------" + "構造函數開始" + "------"); System.out.println("Thread.currentThread().getName() = " + Thread.currentThread().getName()); System.out.println("Thread.currentThread().isAlive() = " + Thread.currentThread().isAlive()); System.out.println("this.getName() = " + this.getName()); System.out.println("this.isAlive() = " + this.isAlive()); System.out.println("Thread.currentThread() == this : " + (Thread.currentThread() == this)); System.out.println("------" + "構造函數結束" + "------"); } @Override public void run(){ System.out.println("------" + "run()開始" + "------"); System.out.println("Thread.currentThread().getName() = " + Thread.currentThread().getName()); System.out.println("Thread.currentThread().isAlive() = " + Thread.currentThread().isAlive()); System.out.println("this.getName() = " + this.getName()); System.out.println("this.isAlive() = " + this.isAlive()); System.out.println("Thread.currentThread() == this : " + (Thread.currentThread() == this)); System.out.println("------" + "run()結束" + "------"); } } public class Main { public static void main(String[] args) { MyThread myThread = new MyThread(); myThread.setName("A"); myThread.start(); } }
運行結果如下:
------構造函數開始------ Thread.currentThread().getName() = main Thread.currentThread().isAlive() = true this.getName() = Thread-0 this.isAlive() = false Thread.currentThread() == this : false ------構造函數結束------ ------run()開始------ Thread.currentThread().getName() = A Thread.currentThread().isAlive() = true this.getName() = A this.isAlive() = true Thread.currentThread() == this : true ------run()結束------
解析構造函數部分:
由於構造函數是被main主線程調用的,所以這里的Thread.currentThread()返回的是主線程main。其實就是表明Thread.currentThread()表示當前代碼段正在被誰調用。
而this就是只當前線程myThread。至於this.getName()=Thread-0是有其內部機制決定的,源碼如下:
private static int threadInitNumber; private static synchronized int nextThreadNum() { return threadInitNumber++; } public Thread() { init(null, null, "Thread-" + nextThreadNum(), 0); }
從中可以看出線程new的時候就會自動生成一個默認線程名。由於此時該線程還沒啟動,所以狀態是false還未啟動。
解析run()方法部分:
由於此時線程開始啟動,所以Thread.currentThread()與this指同一個,即當前線程。然而Thread.currentThread()實際依舊表示當前代碼段正在被誰調用。this指代的才是真正的當前線程。
下面再看第二個例子,依舊使用上面的線程類代碼,只修改測試類如下:
public class Main { public static void main(String[] args) { MyThread myThread = new MyThread(); Thread t1 = new Thread(myThread); System.out.println("main begin myThread isAlive = " + myThread.isAlive()); System.out.println("main begin t1 isAlive = " + t1.isAlive()); t1.setName("A"); t1.start(); System.out.println("main end t1 isAlive = " + t1.isAlive()); System.out.println("main end myThread isAlive = " + myThread.isAlive()); } }
主要區別已經表明,就是線程myThread作為參數傳入另一個線程。
運行結果如下:
------構造函數開始------ Thread.currentThread().getName() = main Thread.currentThread().isAlive() = true this.getName() = Thread-0 this.isAlive() = false Thread.currentThread() == this : false ------構造函數結束------ main begin myThread isAlive = false main begin t1 isAlive = false main end t1 isAlive = true main end myThread isAlive = false ------run()開始------ Thread.currentThread().getName() = A Thread.currentThread().isAlive() = true this.getName() = Thread-0 this.isAlive() = false Thread.currentThread() == this : false ------run()結束------
解析中間一部分:
可以發現內部線程myThread始終沒有開啟過,而外部線程t1在start后開啟,而它實際是調用的內部線程myThread的run方法開啟的。
解析run()方法部分:
Thread.currentThread()與this指向了不通的線程對象。Thread.currentThread()指向的是外部線程,表示當前方法被外部線程t1調用。this指向的是內部線程myThread,狀態依舊是false未開啟狀態。與main方法中的輸出一樣。
總結:
在線程不作為參數傳入另一個線程時,this和Thread.currentThread()【表面上】代表的是同一個對象。而當線程作為參數傳入時,this指向當前對象,即內部線程,而Thread.currentThread()指向當前方法被哪個線程調用的那個對象,即外部線程。