今天開學第一天,進行了一次小測驗,有道題目是這樣的
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()方法來開啓線程。
一道小測試題,一個線程既實現了Runnable接口又繼承Thread方法
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.