「implements Runnable」 和「extends Thread」的不一樣多線程
最近在學習Android中的Handler消息傳遞機制時,建立新線程有兩種方式:一種是實現Runnable接口(implements Runnable)而另外一種則是繼承Thread類(extends Thread)。而這兩種方式有什麼異同呢?帶着這個疑問,Google了一些資料出來,本着分享給你們同時也方便本身查閱複習,寫一篇文章來記錄它。性能
首先看看這兩種方式都是怎樣的?學習
1 public class ThreadA implements Runnable { 2 public void run() { 3 //Code 4 } 5 } 6 //調用 "new Thread(threadA).start()" 來開啓線程 7 8 public class ThreadB extends Thread { 9 public ThreadB() { 10 super("ThreadB"); 11 } 12 public void run() { 13 //Code 14 } 15 } 16 //調用 "threadB.start()" 來開啓線程
兩種方法實現一樣的工做可是它們之間仍是有一些區別的。spa
它們之間的不一樣是:線程
1.咱們都知道,Java是單繼承機制,不容許同時繼承多個類。所以,當你繼承Thread類(extends Thread)後,你就不能再繼承其餘類了。而你實現Runnable接口就不同了,你能夠繼承其餘類了。code
2.當你繼承Thread類時,你的每個Thread對象創造不一樣的對象而後關聯它們。對象
而繼承Runnable接口則不同,多個線程共享一個對象。blog
用一個例子來幫助咱們理解:繼承
1 class ImplementsRunnable implements Runnable { 2 3 private int counter = 0; 4 5 public void run() { 6 counter++; 7 System.out.println("ImplementsRunnable : Counter : " + counter); 8 } 9 } 10 11 class ExtendsThread extends Thread { 12 13 private int counter = 0; 14 15 public void run() { 16 counter++; 17 System.out.println("ExtendsThread : Counter : " + counter); 18 } 19 } 20 21 public class ThreadVsRunnable { 22 23 public static void main(String args[]) throws Exception { 24 //多線程共享一個對象 25 ImplementsRunnable rc = new ImplementsRunnable(); 26 Thread t1 = new Thread(rc); 27 t1.start(); 28 Thread.sleep(1000); // 在開啓下個線程前先等待1秒 29 Thread t2 = new Thread(rc); 30 t2.start(); 31 Thread.sleep(1000); // 在開啓下個線程前先等待1秒 32 Thread t3 = new Thread(rc); 33 t3.start(); 34 35 //爲每個線程創造新的實例 36 ExtendsThread tc1 = new ExtendsThread(); 37 tc1.start(); 38 Thread.sleep(1000); // 在開啓下個線程前先等待1秒 39 ExtendsThread tc2 = new ExtendsThread(); 40 tc2.start(); 41 Thread.sleep(1000); // 在開啓下個線程前先等待1秒 42 ExtendsThread tc3 = new ExtendsThread(); 43 tc3.start(); 44 } 45 }
運行結果:接口
從運行的結果,咱們能夠看出。實現Runnable接口,只建立了一個類的實例,並且被多個線程共享了。所以Counter遞增。而繼承Thread類,你必須爲每個線程建立不一樣的實例。所以每一個類的實例分配了不一樣的內存空間,每個有不一樣的Counter,它們的值相同。這意味着沒有增長由於沒有一個對象的引用是相同的。
那何時用Runnable接口呢?
當你想要在一組線程中訪問相同的資源時,使用Runnable接口。在這種狀況下要避免使用Thread類,由於多對象的建立會佔用更多的內存,會致使大的性能花費。
PS:Thread類內部實現了Runnable接口
最後,哪一種方式最好用呢?
顯而易見,固然是實現Runnable接口更好。