Thread類內部有個run()方法,線程執行時就是執行這個方法,源碼爲:
private Runnable target;
public void run() {
if (target != null) {
target.run();
}
}
其中target是一個Runnable接口對象,可以看到線程在執行時其實是在執行target的run()方法。
創建線程的第一種方式:繼承Thread類,即使用Thread的子類,並重寫run()方法
//1 使用Thread的子類
Thread thread1 = new Thread()
{
@Override
public void run()
{
while(true)
{
System.out.println("thread1: " + Thread.currentThread().getName());
}
}
};
這裏的run()方法不是target的run()方法,是子類重寫的run()方法
//2 傳入Runnable對象
Thread thread2 = new Thread(new Runnable(){
@Override
public void run()
{
while(true)
{
System.out.println("thread2: " + Thread.currentThread().getName());
}
}
});
這裏沒有使用子類繼承的方式,調用的是Thread類的run()方法,從源碼可以看到,該run()方法內部調用的是target的run()方法,就是這裏實現的run()方法
來看一件有意思的事情:
//3 運行誰的run方法?
Thread thread3 = new Thread(new Runnable(){
@Override
public void run()
{
while(true)
{
System.out.println("Runnable對象的run方法: " + Thread.currentThread().getName());
}
}
}){
@Override
public void run()
{
while(true)
{
System.out.println("子類thread3的run方法: " + Thread.currentThread().getName());
}
}
};
這裏構造了Thread子類對象thread3,並且在構造函數中傳入了一個Runnable接口對象給thread3的target成員變量,由於子類重寫了run()方法,所以thread3在執行時會調用重寫的run()方法(第二個run()方法),如果這裏的子類沒有重寫run()方法,很顯然會去調用父類即Thread類的run()方法,該方法內部再去調用target的run()方法,即這裏構造函數裏實現的run()方法(第一個run()方法)。