Thread.currentThread()與this的區別
在自定義執行緒類時,如果執行緒類是繼承java.lang.Thread的話,那麼執行緒類就可以使用this關鍵字去呼叫繼承自父類Thread的方法,this就是當前的物件。
另一方面,Thread.currentThread()可以獲取當前執行緒的引用,一般都是在沒有執行緒物件又需要獲得執行緒資訊時通過Thread.currentThread()獲取當前程式碼段所線上程的引用。
儘管this與Thread.currentThread() 都可以獲取到Thread的引用,但是在某種情況下獲取到的引用是有差別的,下面進行舉例說明
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("------" + "建構函式結束" + "------"); } @Override public void run(){ Thread testThread = Thread.currentThread(); 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 Test {
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
------建構函式結束------
------run()開始------
Thread.currentThread().getName() = A
Thread.currentThread().isAlive() = true
this.getName() = A
this.isAlive() = true
Thread.currentThread() == this : true
------run()結束------
我們會發現this 與 Thread.currentThread()是同一個引用
先說構造方法中的程式碼結果
Thread.currentThread().getName() = main
Thread.currentThread().isAlive() = true
這個結果沒什麼好說的,例項化MyThread,呼叫MyThread構造方法是主執行緒main
this.getName() = Thread-0
this.isAlive() = false
現在,這個this是什麼?MyThread的引用,是個執行緒類,但是這個執行緒類並沒有設定名字,所以Thread預設給了一個Thread-0
預設名字的規則定義如下:
因為僅僅是執行構造方法,還未執行執行緒,所以this.isAlive() = false
之後是run()中的程式碼結果
Thread.currentThread().getName() = A
Thread.currentThread().isAlive() = true
當前執行緒名字為A,A是我們手動賦予的myThread.setName("A");,並且它是執行著的
this.getName() = A
this.isAlive() = true
因為,我們執行的執行緒就是MyThread的引用,而this也是MyThread的引用,所以列印結果與Thread.currentThread()相同,
並且Thread.currentThread() == this : true
當我們保持執行緒類不變,如下修改測試類:
public class Test {
public static void main(String[] args){
MyThread myThread = new MyThread();
// 將執行緒物件以構造引數的方式傳遞給Thread物件進行start()啟動執行緒
Thread newThread = new Thread(myThread);
newThread.setName("A");
newThread.start();
}
}
測試結果如下:
------建構函式開始------
Thread.currentThread().getName() = main
Thread.currentThread().isAlive() = true
this.getName() = Thread-0
this.isAlive() = false
------建構函式結束------
------run()開始------
Thread.currentThread().getName() = A
Thread.currentThread().isAlive() = true
this.getName() = Thread-0
this.isAlive() = false
Thread.currentThread() == this : false
------run()結束------
會發現,我們會發現this 與 Thread.currentThread()不是同一個引用
將執行緒物件以構造引數的方式傳遞給Thread物件進行start()啟動執行緒,我們直接啟動的執行緒實際是newThread,而作為構造引數的myThread,賦給Thread類中的屬性target,之後在Thread的run方法中呼叫target.run();
此時Thread.currentThread()是Thread的引用newThread, 而this依舊是MyThread的引用,所以是不一樣的,列印的內容也不一樣