Thread類實現了Runnable接口嗎?
我們看看源碼中對與Thread類的部分聲明
public class Thread implements Runnable {
/* Make sure registerNatives is the first thing <clinit> does. */
private static native void registerNatives();
static {
registerNatives();
}
private volatile String name;
...
現在是不是很清楚了,Thread 類是實現了Runnable接口的。
實現多線程的兩種方法
第一種方法:繼承Thread類
方法步驟總結:
- 定義一個類繼承Thread;
- 重寫Thread類中的run方法,將需要被多線程執行的代碼存儲到該run方法當中。
- 建立Thread類的子類創建線程對象。
- 直接調用子類從Thread類繼承的start方法,開啟一個線程(調用該線程的run方法)。
第二種方法:實現Runable接口
Thread類有一個Thread(Runnable target)構造方法,在Runable接口類中只有一個run()方法。
當使用Thread(Runnable target)方法創建線程對象時,需要為該方法傳遞一個實現 Runnable接口的對象,這樣創建的線程將調用那個實現了Runnable接口類對象中的run()方法作為其運行代碼,而不再是調用Thread類中的run方法了。
方法步驟總結:
- 定義一個類實現Runnable接口,覆蓋Runnable接口中的run方法,將線程要運行的代碼存放在該run方法中;
- 通過Thread類建立線程對象,將Runnable接口的子類實例對象作為實際參數傳遞給Thread類的構造方法。
兩種方式區別
- 繼承Thread: 線程代碼存放Thread子類run方法中,且該run方法被調用。
- 實現Runnable:線程代碼存在實現了Runnable類接口的對象的run方法中,且該run方法被調用。
注意:啟動一個新的線程,不是直接調用Thread子類的對象的run方法,而是調用Thread子類對象的start方法。
start方法是從Thread類中繼承的方法,Thread類對象的start方法將產生一個新的線程,並在該線程上運行該Thread類對象中的run方法。
根據面向對象的多態性可知,在該線程上實際運行的是我們編寫的那個類(Thread的子類)對象中的run方法。