Thread和Runnable的區別和聯繫、屢次start一個線程會怎麼樣

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

    一、Thread類實現了Runable接口。html

  二、都須要重寫裏面Run方法。java

2、實現Runnable接口相對於繼承Thread類來講,有以下顯著的好處:

 

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

  二、能夠避免因爲Java的單繼承特性帶來的侷限。咱們常常碰到這樣一種狀況,即當咱們要將已經繼承了某一個類的子類放入多線程中,因爲一個類不能同時有兩個父類,因此不能用繼承Thread類的方式,那麼,這個類就只能採用實現Runnable接口的方式了。 

  三、有利於程序的健壯性,代碼可以被多個線程共享,代碼與數據是獨立的。當多個線程的執行代碼來自同一個類的實例時,即稱它們共享相同的代碼。多個線程操做相同的數據,與它們的代碼無關。當共享訪問相同的對象是,即它們共享相同的數據。當線程被構造時,須要的代碼和數據經過一個對象做爲構造函數實參傳遞進去,這個對象就是一個實現了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

 從結果能夠看出:建立了兩個多線程對象,他們分別實現了買票任務; spa

實現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接口的例子因爲同時操做一個資源,會出現線程不安全的狀況,若是狀況須要,咱們須要進行同步操做。code

3、線程屢次調用start方法,引起的異常  

   經過調用Thread類的start()方法來啓動一個線程,這時此線程是處於就緒狀態,並無運行。而後經過此Thread類調用方法run()來完成其運行操做的,這裏方法run()稱爲線程體,它包含了要執行的這個線程的內容,Run方法運行結束,此線程終止,而CPU再運行其它線程,而若是直接用Run方法,這只是調用一個方法而已,程序中依然只有主線程--這一個線程,其程序執行路徑仍是隻有一條,這樣就沒有達到寫線程的目的。

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

  能夠被重複調用的是run()方法。
  Thread類中run()和start()方法的區別以下:
    run()方法:在本線程內調用該Runnable對象的run()方法,能夠重複屢次調用;
    start()方法:啓動一個線程,調用該Runnable對象的run()方法,不能屢次啓動一個線程;
相關文章
相關標籤/搜索