一道小測試題,一個線程既實現了Runnable接口又繼承Thread方法

今天開學第一天,進行了一次小測驗,有道題目是這樣的

public class Test extends Thread implements Runnable {

	@Override
	public void run() {
		// TODO Auto-generated method stub
		for (int i = 0; i < 50; i++) {
			System.out.println("This is the test"+i);
		}
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Thread thread = new Thread(new Test());
		thread.start();
	}

}


問程序是否正確執行,會不會報錯,大家都知道創建線程有兩種方式:

1、繼承Thread類,複寫其run()方法;(這種方式下,每創建一個子類對象就創建了一個線程

優點是,代碼簡單,直接編寫子類繼承Thread類,然後調用new子類對象,直接調用父類的start()方法,start()方法中會調用子類中複寫的run()方法,執行自定義的動作。

缺點是,一旦一個類繼承了其他的類,就不可以再繼承Thread類了。

2、實現Runnable接口,Runnable接口中有一個run()方法,把要執行的代碼放到run()方法中。

優點,解決了Java中單繼承的侷限性,線程實現了Runnable接口,還可以繼承其他對象,該方式創建線程時,會傳入一個實現了Runnable接口的對象,可以多個線程共享這個實現了Runnable接口的對象,適合多線程處理同一份資源的情況(典型例子就是,多窗口同時賣票)

缺點,較之繼承線程的方式創建線程要稍微複雜一些。

實際開發過程中,提倡使用第二種方式創建線程,這種方式比較靈活,更具擴展性。

下面來看下上面的那個程序,Test類既繼承了Thread類,又實現了Runnable接口,主函數中

Thread thread = new Thread(new Test());

其實是使用了第二種創建線程的方式,其中傳入的對象new Test()是實現了Runnable接口的,這裏大家要記住的是Thread類也是實現了Runnable接口的,同樣Thread類的子類也是實現了Runnable接口的,所以以上程序改成下面這樣也是可以的,

public class Test1 extends Thread {

	@Override
	public void run() {
		// TODO Auto-generated method stub
		for (int i = 0; i < 50; i++) {
			System.out.println("This is the test"+this.currentThread().getName()+" "+i);
		}
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
//		Test1 t1 = new Test1();
//		t1.start();
		Thread thread = new Thread(new Test1());
		thread.start();
	}
}

運行結果截圖:



 大家可以看到運行結果:當前線程名爲:Thread-1,大家知道線程的默認命名是按照Thread-x(x是從0開始的整數)的規則命名的,那麼,Thread-0那個線程呢?

這是因爲該類繼承了Thread類,當創建一個子類對象時,就會創建一個線程,但是線程要運行的話,一定要調用它的start()方法來開啓線程。

發佈了30 篇原創文章 · 獲贊 11 · 訪問量 29萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章