多線程能夠經過兩種方式來建立:java
1、經過繼承Thread類。編程
2、經過實現Runnable接口。多線程
那麼中兩種方式到底有什麼區別呢?那種方式更好些呢?ide
先看看幾個簡單的Demo:spa
Demo1線程
public class MyThread { public static void main(String[] args) { ThreadTest t = new ThreadTest(); t.start(); t.start(); t.start(); t.start(); } } class ThreadTest extends Thread { private int n = 10; @Override public void run() { while (n > 0) { System.out.println(Thread.currentThread().getName() + " " + n--); } } }
運行後能夠看出,其實只啓動了一個線程,並且還拋異常了,這個在下面說。code
咱們修改一下代碼:對象
Demo2blog
public class MyThread { public static void main(String[] args) { new ThreadTest().start(); new ThreadTest().start(); new ThreadTest().start(); new ThreadTest().start(); } } class ThreadTest extends Thread { private int n = 10; @Override public void run() { while (n > 0) { System.out.println(Thread.currentThread().getName() + " " + n--); } } }
再次運行,發現這四個線程對象各自佔有各自的資源,並非同時完成統一任務。繼承
咱們能夠得出結論:Thread類實際上沒法達到資源共享的目的。
那麼,Runnable接口能不能達到這一目的呢?
Demo3
public class MyThread { public static void main(String[] args) { RunnableTest r = new RunnableTest(); new Thread(r).start(); new Thread(r).start(); new Thread(r).start(); new Thread(r).start(); } }class RunnableTest implements Runnable { private int n = 10; @Override public void run() { while (n > 0) { System.out.println(Thread.currentThread().getName() + " " + n--); } } }
運行後咱們發現,這四個線程同時完成了統一的任務,能夠達到資源共享的目的
經過以上比較咱們便可得出Thread與Runnable的區別:
一、Runnable適合於多個相同程序代碼線程去處理統一資源的狀況,把虛擬的cpu(線程)同程序的代碼,數據有效分離,較好體現面向對象的編程的思想
二、Runnable能夠避免因爲java的單繼承機制帶來的侷限。能夠再繼承其餘類的同時,還能實現多線程的功能。
三、Runnable能增長程序的健壯性。代碼可以被多個線程共享。
咱們把Demo1的線程start()方法改爲run()試試
public class MyThread { public static void main(String[] args) { ThreadTest t = new ThreadTest(); t.run(); t.run(); t.run(); t.run(); } } class ThreadTest extends Thread { private int n = 10; @Override public void run() { while (n > 0) { System.out.println(Thread.currentThread().getName() + " " + n--); } } }
運行後結果:
把Demo2的全部線程的start方法改爲run試試
public class MyThread { public static void main(String[] args) { new ThreadTest().run(); new ThreadTest().run(); new ThreadTest().run(); new ThreadTest().run(); } } class ThreadTest extends Thread { private int n = 10; @Override public void run() { while (n > 0) { System.out.println(Thread.currentThread().getName() + " " + n--); } } }
運行後結果:
由此咱們能夠區別:
一、start()方法:啓動一個線程,不能屢次啓動一個線程。
二、run()方法:在本線程內調用run()方法,能夠重複屢次調用。
三、用start()方法來啓動線程,真正實現了多線程運行,這時無需等待run方法體代碼執行完畢而直接繼續執行下面的代碼。
四、run()方法只是類的一個普通方法而已,若是直接調用Run方法,程序中依然只有主線程這一個線程,其程序執行路徑仍是隻有一條,仍是要順序執行,要等待run方法體執行完畢後纔可繼續執行下面的代碼。