1. 程式人生 > >Thread.currentThread().getName() 和 this.getName()區別詳解

Thread.currentThread().getName() 和 this.getName()區別詳解

區別 pac 修改 face 通過 同名 exce splay 情況

Thread.currentThread().getName() 和 this.getName()區別詳解


<<Java多線程編程核心技術>>這本書裏說到了這個: Thread.currentThread().getName() this.getName()他倆是有區別的,得到的效應是不一樣的,首先,從直觀上來說:Thread.currentThread().getName() 是一個靜態方法
this.getName()是一個實例方法

實例方法,一般情況下是:反映這個實例的情況靜態方法,一般情況下是:反映這個實體
的情況
實例指的就是這個類的對象實體卻不一樣,實體是指正在發生這個作用的實例
上代碼:
  1. public class MyThread extends Thread {
  2. public MyThread(){
  3. System.out.println("---MyThread begin---");
  4. System.out.println("Thread.currentThread.getName()=" +Thread.currentThread().getName());
  5. System.out.println("this.getName()=" + this
    .getName());
  6. System.out.println(Thread.currentThread() == this);
  7. System.out.println("---MyThread begin---");
  8. }
  9. @Override
  10. public void run(){
  11. System.out.println("---run begin---");
  12. System.out.println("Thread.currentThread.getName()=" +Thread.currentThread().getName
    ());
  13. System.out.println("this.getName()=" +this.getName());
  14. System.out.println(Thread.currentThread() == this);
  15. System.out.println("---run end ---");
  16. }
  17. public static void main(String[] args) throws InterruptedException {
  18. MyThread tt = new MyThread();
  19. Thread t1 = new Thread(tt);
  20. t1.setName("test");
  21. t1.start();
  22. }
  23. }
輸出:
  1. ---MyThread begin---
  2. Thread.currentThread.getName()=main //實體是指現在正在發生的線程:main線程
  3. this.getName()=Thread-0 //實例:當前實例是“死的線程”,默認賦值是:Thread-0
  4. false // 實體並不是實例
  5. ---MyThread begin---

  6. ---run begin---
  7. Thread.currentThread.getName()=test //實體是指現在正在發生的線程:test線程
  8. this.getName()=Thread-0 //實例:當前實例是“死的線程”,默認賦值是:Thread-0
  9. false //當前的實體是:test 並不是,tt這個對象的死線程
  10. ---run end ---
調用MyThread構造函數的是main線程Thread.currentThread().getName()=mainThread.currentThread().isAlive()=true
而此時還沒有啟動MyThread子線程,所以打印出this.getName=Thread-0this.isAlive()=false
此時this代表的是MyThread對象實例,所以Thread.currentThread()==this :false

this.getName() = Thread-0 是為什麽呢通過查看Thread源碼發現,在Thread類的構造方法中,默認會自動給name賦值:
  1. public Thread(Runnable target) {
  2. init(null, target, "Thread-" + nextThreadNum(), 0);
  3. }
在Thread源碼中實際上new Thread(tt)會將tt應用的對象綁定到一個private變量target上,在t1被執行的時候即t1.run()被調用的時候,它會調用target.run()方法,也就是說它是直接調用tt對象的run方法,也就是說,在run方法被執行的時候,this.getName()實際上返回的是target.getName(),而Thread.currentThread().getName()實際上是t1.getName()修改代碼直接執行MyThread的線程:
  1. public static void main(String[] args) throws InterruptedException {
  2. MyThread tt = new MyThread();
  3. tt.setName("test");
  4. tt.start();
  5. }

輸出:
  1. ---MyThread begin---
  2. Thread.currentThread.getName()=main
  3. this.getName()=Thread-0
  4. false
  5. ---MyThread begin---
  6. ---run begin---
  7. Thread.currentThread.getName()=test
  8. this.getName()=test
  9. true
  10. ---run end ---

總結幾點:
  • 一個進程裏main是一開始就活著的,但是,它跟main方法半毛錢關系都沒有,僅僅是同名罷了
  • 誰調用了start函數,誰才把自己交給線程調度器,誰才是活著的線程,否則,管你繼承啥,還是實現啥,都是一個普通的對象
  • 實現了Runable接口的對象具有運行線程的資格,但是,只要它不被start,它就是一個普通的對象,有資格,並不代表它就是線程,線程是活著的東西,對象是死的
  • 線程可以級級包裹嵌套,就像上邊一樣,它運行的是:target的run
  • 自己調用run的話,僅僅就是一個函數調用,要讓調度器去調用,它才是一個線程

Thread.currentThread().getName() 和 this.getName()區別詳解