一、Thread類實現了Runable接口。html
二、都須要重寫裏面Run方法。java
一、適合多個相同程序代碼的線程去處理同一資源的狀況,把虛擬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
一個線程對象只能調用一次start方法.從new到等待運行是單行道,因此若是你對一個已經啓動的線程對象再調用一次start方法的話,會產生:IllegalThreadStateException異常.htm
能夠被重複調用的是run()方法。
Thread類中run()和start()方法的區別以下:
run()方法:在本線程內調用該Runnable對象的run()方法,能夠重複屢次調用;
start()方法:啓動一個線程,調用該Runnable對象的run()方法,不能屢次啓動一個線程;