- l 創建線程的第一種方式:繼承Thread類。
步驟:
1,定義類繼承Thread。
2,復寫Thread類中的run方法。
目的:將自定義代碼存儲在run方法。讓線程運行。//run();僅僅是對象調用方法。而線程創建了,並沒有運行。
3,調用線程的start方法,
該方法兩個作用:啟動線程,調用run方法。
Demo d = new Demo();//創建好一個線程。
//d.start();//開啟線程並執行該線程的run方法。
d.run();//僅僅是對象調用方法。而線程創建了,並沒有運行。
- l 創建線程的第二種方式:實現Runable接口
步驟:
1,定義類實現Runnable接口
2,覆蓋Runnable接口中的run方法。
將線程要運行的代碼存放在該run方法中。
3,通過Thread類建立線程對象。
4,將Runnable接口的子類對象作為實際參數傳遞給Thread類的構造函數。
為什么要將Runnable接口的子類對象傳遞給Thread的構造函數。
因為,自定義的run方法所屬的對象是Runnable接口的子類對象。
所以要讓線程去指定指定對象的run方法。就必須明確該run方法所屬對象。
5,調用Thread類的start方法開啟線程並調用Runnable接口子類的run方法。
- l 實現方式和繼承方式有什么區別呢?
實現方式好處:避免了單繼承的局限性。
在定義線程時,建立使用實現方式。
兩種方式區別:
繼承Thread: 線程代碼存放Thread子類run方法中。
實現Runnable,線程代碼存在接口的子類的run方法。
實現Runnable接口相對於繼承Thread類來說,有如下的顯著優勢:
1.適合多個相同代碼的線程去處理同一個資源的情況
2.可以避免由於java的單繼承特性帶來的局限
3.增強了程序的健壯性,代碼能夠被多個線程共享,代碼與數據時獨立的
給你個例子,你自己取運行就知道了,好好對比下
1 class MyThread extends Thread{ // 繼承Thread類,作為線程的實現類 2 private int ticket = 5 ; // 表示一共有5張票 3 public void run(){ // 覆寫run()方法,作為線程 的操作主體 4 for(int i=0;i<100;i++){ 5 if(this.ticket>0){ 6 System.out.println("賣票:ticket = " + ticket--) ; 7 } 8 } 9 } 10 }; 11 public class ThreadDemo0{ 12 public static void main(String args[]){ 13 MyThread mt1 = new MyThread() ; // 實例化對象 14 MyThread mt2 = new MyThread() ; // 實例化對象 15 MyThread mt3 = new MyThread() ; // 實例化對象 16 mt1.run() ; // 調用線程主體 17 mt2.run() ; // 調用線程主體 18 mt3.run() ; // 調用線程主體 19 } 20 }; 21 22 23 class MyThread implements Runnable{ // 繼承Thread類,作為線程的實現類 24 private int ticket = 5 ; // 表示一共有5張票 25 public void run(){ // 覆寫run()方法,作為線程 的操作主體 26 for(int i=0;i<100;i++){ 27 if(this.ticket>0){ 28 System.out.println("賣票:ticket = " + ticket--) ; 29 } 30 } 31 } 32 }; 33 public class RunnableDemo0{ 34 public static void main(String args[]){ 35 MyThread mt = new MyThread() ; // 實例化對象 36 new Thread(mt).run() ; // 調用線程主體 37 new Thread(mt).run() ; // 調用線程主體 38 new Thread(mt).run() ; // 調用線程主體 39 } 40 };
簡單的來說,就是繼承和實現接口的區別。
1、當使用繼承的時候,主要是為了不必重新開發,並且在不必了解實現細節的情況下擁有了父類我所需要的特征。它也有一個很大的缺點,那就是如果我們的類已經從一個類繼承(如小程序必須繼承自 Applet 類),則無法再繼承 Thread 類,
2、java只能單繼承,因此如果是采用繼承Thread的方法,那么在以后進行代碼重構的時候可能會遇到問題,因為你無法繼承別的類了,在其他的方面,兩者之間並沒什么太大的區別。
3、implement Runnable是面向接口,擴展性等方面比extends Thread好。
4、使用 Runnable 接口來實現多線程使得我們能夠在一個類中包容所有的代碼,有利於封裝,它的缺點在於,我們只能使用一套代碼,若想創建多個線程並使各個線程執行不同的代碼,則仍必須額外創建類,如果這樣的話,在大多數情況下也許還不如直接用多個類分別繼承 Thread 來得緊湊。