“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 //Code14 }15 }16 //調用 "threadB.start()" 來開啟線程兩種方法實現同樣的工作但是它們之間還是有一些區別的。
它們之間的不同是:
1.我們都知道,Java是單繼承機制,不允許同時繼承多個類。因此,當你繼承Thread類(extends Thread)后,你就不能再繼承其他類了。而你實現Runnable接口就不一樣了,你可以繼承其他類了。
2.當你繼承Thread類時,你的每一個Thread對象創造不同的對象然后關聯它們。
而繼承Runnable接口則不一樣,多個線程共享一個對象。
用一個例子來幫助我們理解:
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接口更好。
新聞熱點
疑難解答