第一個例子
看一個很簡單的例子:
public class MyThread extends Thread {
public MyThread() {
super();
System.out.println("構造方法currentThread:"+Thread.currentThread().getName());
System.out.println("構造方法this:"+this.getName());
}
@Override
public void run() {
System.out.println("run方法currentThread:"+Thread.currentThread().getName());
System.out.println("run方法this:"+this.getName());
}
}
public class TestMain {
public static void main(String[] args) {
MyThread myThread=new MyThread();
myThread.setName("myThread");
myThread.start();
}
}
輸出如下
構造方法currentThread:main
構造方法this:Thread-0
run方法currentThread:myThread
run方法this:myThread
第一行:構造方法中Thread.currentThread().getName()很明顯當前執(zhí)行的線程是main線程
第二行:構造方法中的this.getName()為什么是Thread-0呢?點進Thread類的無參構造方法中看到源碼如下,Thread為每一個線程默認取了一個名字
public Thread() {
init(null, null, "Thread-" + nextThreadNum(), 0);
}
第三行:run方法中Thread.currentThread().getName()),當前執(zhí)行的線程就是myThread,執(zhí)行run方法之前我們已經(jīng)為myThread對象設置了名字,所以name為myThread,誰調(diào)用start()方法,currentThread就是誰。
第四行:run方法中的this.getName(),而run方法中this對象就是myThread對象,在這個例子中,我們首先調(diào)用了myThread對象的start方法,start方法又回調(diào)了myThread類的run方法,所以自始至終都只有myThread對象一個

第二個例子
MyThread類不變,測試類修改為如下,把myThread對象當做Thread的參數(shù)傳進去
public class TestMain {
public static void main(String[] args) {
MyThread myThread=new MyThread();
myThread.setName("myThread");
Thread thread=new Thread(myThread,"thread");
thread.start();
}
}
輸出如下:
構造方法currentThread:main
構造方法this:Thread-0
run方法currentThread:thread
run方法this:myThread
前兩個就不用說了,第三行run方法中currentThread為thread對象,誰調(diào)用的start()方法,currentThread就是誰。
第四行run方法中的this為myThread對象,而在這個例子中,我們首先調(diào)用了thread對象的start()方法,thread對象的start方法回調(diào)了thread類的run方法,thread類的run方法中調(diào)用了target的run方法,所以this就指向了target,而target正是我們傳入的myThread對象


看一下Thread的有參構造方法
public Thread(Runnable target, String name) {
init(null, target, name, 0);
}
再看Thread類的run方法
@Override
public void run() {
if (target != null) {
target.run();
}
}
關于為什么調(diào)用了start()方法會執(zhí)行run()方法參考此篇文章https://blog.csdn.net/qq_38799155/article/details/78488161