Thread和Runnable的區別和聯系、多次start一個線程會怎么樣


一、Java有兩種方式實現多線程,第一個是繼承Thread類,第二個是實現Runnable接口。他們之間的聯系:

    1、Thread類實現了Runable接口。

  2、都需要重寫里面Run方法。

二、實現Runnable接口相對於繼承Thread類來說,有如下顯著的好處:

 

  1、適合多個相同程序代碼的線程去處理同一資源的情況,把虛擬CPU(線程)同程序的代碼,數據有效的分離,較好地體現了面向對象的設計思想。 

  2、可以避免由於Java的單繼承特性帶來的局限。我們經常碰到這樣一種情況,即當我們要將已經繼承了某一個類的子類放入多線程中,由於一個類不能同時有兩個父類,所以不能用繼承Thread類的方式,那么,這個類就只能采用實現Runnable接口的方式了。 

  3、有利於程序的健壯性,代碼能夠被多個線程共享,代碼與數據是獨立的。當多個線程的執行代碼來自同一個類的實例時,即稱它們共享相同的代碼。多個線程操作相同的數據,與它們的代碼無關。當共享訪問相同的對象是,即它們共享相同的數據。當線程被構造時,需要的代碼和數據通過一個對象作為構造函數實參傳遞進去,這個對象就是一個實現了Runnable接口的類的實例。

看一下以繼承Thread的賣票例子:

 
class MyThread extends Thread{  
    private int ticket = 5;  
    public void run(){  
    	 while(true){
    		 System.out.println("Thread ticket = " + ticket--);  
             if(ticket < 0){  
                break;
             }  
         }  
    }  
}  
public static void main(String[] args) {					
	new MyThread().start();
	new MyThread().start();
			
}

  輸出結果:

Thread ticket = 5
Thread ticket = 5
Thread ticket = 4
Thread ticket = 4
Thread ticket = 3
Thread ticket = 2
Thread ticket = 3
Thread ticket = 1
Thread ticket = 2
Thread ticket = 0
Thread ticket = 1
Thread ticket = 0

 從結果可以看出:創建了兩個多線程對象,他們分別實現了買票任務; 

實現Runnable接口的賣票例子:

class MyThread2 implements Runnable{  
    private int ticket = 5;  
    public void run(){  
    	 while(true){
    		 System.out.println("Runnable ticket = " + ticket--);  
             if(ticket < 0){  
                break;
             }  
         } 
    }  
}  


<pre name="code" class="html">public static void main(String[] args) {
	MyThread2 m=new MyThread2();
	  new Thread(m).start();
	  new Thread(m).start();
		
			
}

輸出結果:

1 Runnable ticket = 5
2 Runnable ticket = 4
3 Runnable ticket = 3
4 Runnable ticket = 2
5 Runnable ticket = 1
6 Runnable ticket = 0

從結果可以看出雖然我們聲明了兩個線程,但是一共賣了6張票。他們實現了資源共享。PS:在實際開發中,一定要注意命名規范,其次上面實現Runable接口的例子由於同時操作一個資源,會出現線程不安全的情況,如果情況需要,我們需要進行同步操作。

三、線程多次調用start方法,引發的異常  

   通過調用Thread類的start()方法來啟動一個線程,這時此線程是處於就緒狀態,並沒有運行。然后通過此Thread類調用方法run()來完成其運行操作的,這里方法run()稱為線程體,它包含了要執行的這個線程的內容,Run方法運行結束,此線程終止,而CPU再運行其它線程,而如果直接用Run方法,這只是調用一個方法而已,程序中依然只有主線程--這一個線程,其程序執行路徑還是只有一條,這樣就沒有達到寫線程的目的。

  一個線程對象只能調用一次start方法.從new到等待運行是單行道,所以如果你對一個已經啟動的線程對象再調用一次start方法的話,會產生:IllegalThreadStateException異常.

  可以被重復調用的是run()方法。
  Thread類中run()和start()方法的區別如下:
    run()方法:在本線程內調用該Runnable對象的run()方法,可以重復多次調用;
    start()方法:啟動一個線程,調用該Runnable對象的run()方法,不能多次啟動一個線程;

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM