1. 程式人生 > >extends Thread 與 implements Runnable 的區別

extends Thread 與 implements Runnable 的區別

1、通過實現Runnable介面建立執行緒

(1).定義一個類實現Runnable介面,重寫介面中的run()方法。在run()方法中加入具體的任務程式碼或處理邏輯。

(2).建立Runnable介面實現類的物件。

(3).建立一個Thread類的物件,需要封裝前面Runnable介面實現類的物件。(介面可以實現多繼承)

(4).呼叫Thread物件的start()方法,啟動執行緒

  1. publicclass ThreadFromRunnable implements Runnable {  
  2.     //static int count = 10;
  3.     publicvoid run() {  
  4.         int count = 10;  
  5.         System.out.println("\t#"+Thread.currentThread().getName()+" got count from " + count);  
  6.         while(count > 0)  
  7.         {  
  8.             System.out.println("#"+Thread.currentThread().getName()+" : "+ count--);  
  9.         }  
  10.         System.out.println("#"+Thread.currentThread().getName()+
    " : exiting "+ count--);  
  11.     }  
  12.     publicstaticvoid main(String[] args)  
  13.     {  
  14.         ThreadFromRunnable tr = new ThreadFromRunnable();  
  15.         Thread thread = new Thread(tr);  
  16.         Thread thread2 = new Thread(tr);  
  17.         thread.start();  
  18.         thread2.start();  
  19.     }  
  20. }  
output:

#Thread-0 got count from 10
#Thread-1 got count from 10
#Thread-1 : 10
#Thread-1 : 9
#Thread-1 : 8
#Thread-1 : 7
#Thread-1 : 6
#Thread-1 : 5
#Thread-1 : 4
#Thread-0 : 10
#Thread-1 : 3
#Thread-0 : 9
#Thread-1 : 2
#Thread-0 : 8
#Thread-1 : 1
#Thread-0 : 7
#Thread-1 : exiting 0
#Thread-0 : 6
#Thread-0 : 5
#Thread-0 : 4
#Thread-0 : 3
#Thread-0 : 2
#Thread-0 : 1
#Thread-0 : exiting 0

2、通過繼承Thread類建立執行緒

(1).首先定義一個類去繼承Thread父類,重寫父類中的run()方法。在run()方法中加入具體的任務程式碼或處理邏輯。
(2).直接建立一個ThreadDemo2類的物件,也可以利用多型性,變數宣告為父類的型別。

(3).呼叫start方法,執行緒t啟動,隱含的呼叫run()方法。

  1. publicclass ThreadExtendsThread extends Thread {  
  2.     //static int count =10;
  3.     publicvoid run()  
  4.     {  
  5.         int count =10;  
  6.         System.out.println("\t#"+Thread.currentThread().getName()+" got count from " + count);  
  7.         while(count > 0)  
  8.         {  
  9.             System.out.println("{1}quot;+this.getName()+" : "+count--);  
  10.         }  
  11.         System.out.println("{1}quot;+this.getName()+" : existing count=" + count);  
  12.     }  
  13.     publicstaticvoid main(String[] args)  
  14.     {  
  15.         ThreadExtendsThread thread = new ThreadExtendsThread();  
  16.         ThreadExtendsThread thread2 = new ThreadExtendsThread();  
  17.         thread.start();  
  18.         thread2.start();  
  19.     }  
  20. }  
output:

#Thread-0 got count from 10
#Thread-1 got count from 10
$Thread-1 : 10
$Thread-1 : 9
$Thread-1 : 8
$Thread-1 : 7
$Thread-1 : 6
$Thread-1 : 5
$Thread-1 : 4
$Thread-1 : 3
$Thread-1 : 2
$Thread-1 : 1
$Thread-0 : 10
$Thread-1 : existing count=0
$Thread-0 : 9
$Thread-0 : 8
$Thread-0 : 7
$Thread-0 : 6
$Thread-0 : 5
$Thread-0 : 4
$Thread-0 : 3
$Thread-0 : 2
$Thread-0 : 1
$Thread-0 : existing count=0

3、兩種方式的比較

首先分析兩種方式的輸出結果,同樣是建立了兩個執行緒,為什麼結果不一樣呢?

使用實現Runnable介面方式建立執行緒可以共享同一個目標物件(TreadDemo1 tt=new TreadDemo1();),實現了多個相同執行緒處理同一份資源。

然後再看一段來自JDK的解釋:

TheRunnableinterface should be implemented by any class whose instances are intended to be executed by a thread. The class must define a method of no arguments calledrun.

This interface is designed to provide a common protocol for objects that wish to execute code while they are active. For example,Runnableis implemented by classThread. Being active simply means that a thread has been started and has not yet been stopped.

In addition,Runnableprovides the means for a class to be active while not subclassingThread. A class that implementsRunnablecan run without subclassingThreadby instantiating aThreadinstance and passing itself in as the target. In most cases, theRunnableinterface should be used if you are only planning to override therun()method and no otherThreadmethods. This is important because classes should not be subclassed unless the programmer intends on modifying or enhancing the fundamental behavior of the class.

採用繼承Thread類方式:
(1)優點:編寫簡單,如果需要訪問當前執行緒,無需使用Thread.currentThread()方法,直接使用this,即可獲得當前執行緒。
(2)缺點:因為執行緒類已經繼承了Thread類,所以不能再繼承其他的父類。
採用實現Runnable介面方式:
(1)優點:執行緒類只是實現了Runable介面,還可以繼承其他的類。在這種方式下,可以多個執行緒共享同一個目標物件,所以非常適合多個相同執行緒來處理同一份資源的情況,從而可以將CPU程式碼和資料分開,形成清晰的模型,較好地體現了面向物件的思想。
(2)缺點:程式設計稍微複雜,如果需要訪問當前執行緒,必須使用Thread.currentThread()方法。