總結起來一句話:在Thread中調用this其實就是調用Thread私有Runnable類型的target,target是Thread類的一個屬性,而Thread.currentThread()是指新New出來的實例Thread類。兩個是不同的對象。實例化一個Thread的對象,都會將其賦值給Thread的私有target屬性。
直接上代碼:
注意代碼中紅色部分,就可以解釋this和Thread.currentThread()的區別。實際上new Thread(Runnable),new Thread(Runnable,String) 會將一個thread( Thread 是Runnable接口的實現類) 應用的對象綁定到一個pravite變量target上,在t1被執行的時候即t1.run()被調用的時候,它會調用target.run()方法,也就是說它是直接調用thread對象的run方法,再確切的說,在run方法被執行的時候,this.getName()實際上返回的target.getName(),而Thread.currentThread().getName()實際上是t1.getName()。
new Thread(Runnable)的源碼
1 public Thread(Runnable target) { 2 init(null, target, "Thread-" + nextThreadNum(), 0); 3 }
1 public class TestThread { 2 3 public static void main(String[] args) { 4 Bed b = new Bed(); 5 b.start(); 6 Thread t1 = new Thread(b,"B"); 7 System.out.println("main begin t1 isAlive=" + t1.isAlive()); 8 // t1.setName("B"); 9 t1.start(); 10 System.out.println("main end t1 isAlive=" + t1.isAlive()); 11 12 } 13 } 14 15 class Bed extends Thread { 16 17 public Bed() { 18 System.out.println("Bed Constructor---begin"); 19 System.out.println("Thread.currentThread().getName()=" + Thread.currentThread().getName());// 獲取線程名 20 System.out.println("Thread.currentThread().isAlive()=" + Thread.currentThread().isAlive()); // 查看線程是否存活 21 System.out.println("this.getName=" + this.getName()); 22 System.out.println("this.isAlive()=" + this.isAlive()); 23 System.out.println("Thread.currentThread()==this :" + (Thread.currentThread() == this)); 24 System.out.println("Bed Constructor---end "); 25 } 26 27 @Override 28 public void run() { 29 System.out.println("run---begin"); 30 System.out.println("Thread.currentThread().getName=" + Thread.currentThread().getName()); 31 System.out.println("Thread.currentThread().isAlive()" + Thread.currentThread().isAlive()); 32 System.out.println("Thread.currentThread()==this :" + (Thread.currentThread() == this)); 33 System.out.println("this.getName()=" + this.getName()); 34 System.out.println("this.isAlive()=" + this.isAlive()); 35 System.out.println("run --- end"); 36 } 37 }
結果:
1 Bed Constructor---begin 2 Thread.currentThread().getName()=main 3 Thread.currentThread().isAlive()=true 4 this.getName=Thread-0 5 this.isAlive()=false 6 Thread.currentThread()==this :false 7 Bed Constructor---end 8 main begin t1 isAlive=false 9 run---begin 10 Thread.currentThread().getName=Thread-0 11 Thread.currentThread().isAlive()true 12 Thread.currentThread()==this :true 13 this.getName()=Thread-0 14 this.isAlive()=true 15 run --- end 16 main end t1 isAlive=true 17 run---begin 18 Thread.currentThread().getName=B 19 Thread.currentThread().isAlive()true 20 Thread.currentThread()==this :false 21 this.getName()=Thread-0 22 this.isAlive()=false 23 run --- end
b.start()的時候,就是調用Thread的run方法,而newThread對象的時候將其賦給target對象,如果未指定名稱系統默認給target命名,target是線程類Thread的一個私有Runnable類型屬性。
1 private Runnable target;
即使將target和new Thread的線程賦值一樣的名稱也不會出現this==Thread.currentThread(),從而說明target和new Thread()是兩個不同的對象。
1 public class TestThread { 2 3 public static void main(String[] args) { 4 5 Bed b = new Bed("A"); 6 b.start(); 7 Thread t1 = new Thread(b,"A"); 8 System.out.println("main begin t1 isAlive=" + t1.isAlive()); 9 t1.start(); 10 System.out.println("main end t1 isAlive=" + t1.isAlive()); 11 12 } 13 14 }
結果:
1 Bed Constructor---begin 2 Thread.currentThread().getName()=main 3 Thread.currentThread().isAlive()=true 4 this.getName=A 5 this.isAlive()=false 6 Thread.currentThread()==this :false 7 Bed Constructor---end 8 run---begin 9 Thread.currentThread().getName=A 10 Thread.currentThread().isAlive()true 11 Thread.currentThread()==this :true 12 this.getName()=A 13 this.isAlive()=true 14 run --- end 15 main begin t1 isAlive=false 16 main end t1 isAlive=true 17 run---begin 18 Thread.currentThread().getName=A 19 Thread.currentThread().isAlive()true 20 Thread.currentThread()==this :false 21 this.getName()=A 22 this.isAlive()=false 23 run --- end
Reference
[1] https://www.cnblogs.com/huangyichun/p/6071625.html