1. 程式人生 > >Thread.currentThread()與this的區別

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的引用,所以是不一樣的,列印的內容也不一樣