Java創建子線程的兩條不歸路

Java創建子線程的兩條不歸路

摘要:
   其實兩種方法歸結起來看還是一種,都是利用Thread的構造器進行創建,區別就是一種是無參的,一種是有參的。

一、繼承Thread線程類:
  通過繼承Thread類,重寫run方法,子類對象就可以調用start方法啓動線程,JVM就會調用此線程的run方法。
代碼如下:

public class MyThread extends Thread {
    public MyThread() { 
        super(); 
    }
        @Override
        public void run() { 
  	 }
        // 線程執行結束
        System.out.println("執行完成! " + getName());
    }
}

public class HelloWorld {
public static void main(String[] args) {
    // 創建線程t1
    Thread t1 = new MyThread();// 開始線程t1
    t1.start();
}
}

注意: 如果直接調用run方法,程序只會按照順序執行主線程這一個線程。不會創建一個線程。

public class HelloWorld {
public static void main(String[] args) {
    // 創建線程t1
    Thread t1 = new MyThread();// 開始線程t1
    t1.run();
}
}


二、實現Runnable接口:
   因爲Thread類實現了Runnable接口,我們可以直接實現Runnable,然後通過Thread(Runnable target)來創建線程。

//線程執行對象
public class Runner implements Runnable { 
        // 編寫執行線程代碼
        @Override
        public void run() { 
        }
        // 線程執行結束
        System.out.println("執行完成! " + Thread.currentThread().getName());
    }
}


public class HelloWorld {
    public static void main(String[] args) {
        // 創建線程t1,參數是一個線程執行對象Runner
        Thread t1 = new Thread(new Runner()); 
        // 開始線程t1
        t1.start(); 
    }
}

注意: (1)實現Runnable接口,就不能調用Thread類的方法了,但是可以通過Thread.currentThread()進行調用。
(2)可能有的人很好奇,thread.start();爲什麼調用我們實現Runnable類的run方法,而不是Thread類的run方法。這就要從源碼分析了:

//Thread的run方法,調用target.run()
public void run() {
        if (target != null) {
            target.run();
        }
 }
 //Thread的構造器
public Thread(Runnable target) {
        init(null, target, "Thread-" + nextThreadNum(), 0);
}

Thread類的構造器會調用init方法,會把我們傳過去的Runnable對象賦值給Thread類的target,所以target.run()就是我們實現Runnable類,調用重寫的run方法。

private Runnable target;


二、比較創建線程的兩種方法:

開發中:優先選擇,實現Runnable接口的方式

原因:(1)實現的方式沒有類的單繼承的侷限性

   (2)實現的方式更適合來處理多個線程共享數據的情況。

聯繫: Thread實現了Runnable

相同點: 兩者都需要重寫run()。


總結:兩種方法各有好壞,所謂蘿蔔青菜各有所愛,除了自身喜好,別忘了實際的應用場景。(◔◡◔)


哪裏寫得不好或者想討論的小夥伴歡迎留言哦!
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章