該方法將咱們本身定義的一個線程類繼承自Thread類,並重寫run()方法來重定義該線程所進行的操做。
線程類:java
public class Thread1 extends Thread { // 重寫方法重定義該線程進行的操做 @Override public void run() { for (int i = 0; i < 10; i++) { System.out.println(Thread.currentThread().getName() + "執行" + i); } } }
測試類:多線程
public class Main { public static void main(String[] args) { // 啓動線程 new Thread1().start(); for (int i = 0; i < 10; i++) { System.out.println(Thread.currentThread().getName() + "執行" + i); } } }
結果:ide
main執行0 Thread-0執行0 main執行1 Thread-0執行1 main執行2 Thread-0執行2 main執行3 Thread-0執行3 main執行4 Thread-0執行4 main執行5 main執行6 main執行7 main執行8 Thread-0執行5 main執行9 Thread-0執行6 Thread-0執行7 Thread-0執行8 Thread-0執行9
咱們自定義的線程和主線程交替凌亂地執行。函數
線程類:測試
public class Thread2 implements Runnable { // 重寫run方法重定義線程執行的內容 @Override public void run() { for (int i = 0; i < 10; i++) { System.out.println(Thread.currentThread().getName() + "執行" + i); } } }
測試類:this
public class Main { public static void main(String[] args) { new Thread(new Thread2()).start(); for (int i = 0; i < 10; i++) { System.out.println(Thread.currentThread().getName() + "執行" + i); } } }
注意這種狀況的線程建立方式是將實現了Runnable接口的類填入到Thread方法的構造函數中來建立的,與第一種方法直接建立對應的繼承自Thread類的子類的方式有所區別。
執行結果:線程
Thread-0執行0 main執行0 Thread-0執行1 main執行1 Thread-0執行2 main執行2 Thread-0執行3 main執行3 Thread-0執行4 main執行4 Thread-0執行5 main執行5 Thread-0執行6 main執行6 main執行7 Thread-0執行7 main執行8 Thread-0執行8 main執行9 Thread-0執行9
實質上匿名內部類的方法就是實現Runnable接口,只不過這個類沒有名字。
測試類:code
public class Main { public static void main(String[] args) { // 之內部類的方式實現Runnable接口 new Thread(new Runnable() { // 重寫run方法來重定義線程執行的內容 @Override public void run() { for (int i = 0; i < 10; i++) { System.out.println(Thread.currentThread().getName() + "執行" + i); } } }).start(); // 開啓線程 for (int i = 0; i < 10; i++) { System.out.println(Thread.currentThread().getName() + "執行" + i); } } }
執行結果:繼承
Thread-0執行0 Thread-0執行1 Thread-0執行2 Thread-0執行3 Thread-0執行4 Thread-0執行5 Thread-0執行6 Thread-0執行7 main執行0 Thread-0執行8 main執行1 main執行2 main執行3 main執行4 main執行5 main執行6 main執行7 main執行8 main執行9 Thread-0執行9
主要的區別有亮點:
1.由於java是單繼承的機制,因此若是你選擇使用繼承Thread類的方式實現多線程,則沒法再繼承別的類實現對應的功能,而實現Runnable接口則不會有這樣的問題。
2.繼承Thread類不適合資源共享,而實現Runnable接口則適合實現資源共享,下面舉個例子進行說明。
繼承Thread類:接口
class MyThread extends Thread { private int count = 15; private String name; public MyThread(String name) { this.name = name; } @Override public void run() { for (int i = 0;i < 5;i++){ System.out.println(name + "執行 " + count); count--; } } } public class Main { public static void main(String[] args) { new MyThread("1").start(); new MyThread("2").start(); } }
執行結果:
1執行 15 2執行 15 2執行 14 1執行 14 2執行 13 1執行 13 2執行 12 1執行 12 2執行 11 1執行 11
實現Runnable接口:
class MyRunnable implements Runnable { private int count = 15; @Override public void run() { for (int i = 0; i < 5; i++) { System.out.println(Thread.currentThread().getName() + "執行" + count); count--; } } } public class Main { public static void main(String[] args) { MyRunnable myRunnable = new MyRunnable(); // 下面兩個開始的線程都來於同一個線程類,所以類中的屬性能夠共享 new Thread(myRunnable, "3").start(); new Thread(myRunnable, "4").start(); } }
執行結果:
3執行15 4執行15 3執行14 3執行12 3執行11 3執行10 4執行13 4執行8 4執行7 4執行6
從執行的結果就能夠看出使用實現Runnable接口的方法能夠是的多個線程共享同一個資源變得可能,所以在資源共享性上更勝一籌。