extends Thread 與 implements Runnable 的區別

1、通過實現Runnable接口創建線程

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

(2).創建Runnable接口實現類的對象。

(3).創建一個Thread類的對象,需要封裝前面Runnable接口實現類的對象。(接口可以實現多繼承)

(4).調用Thread對象的start()方法,啓動線程

public class ThreadFromRunnable implements Runnable {

	//static int count = 10;
	public void run() {
		int count = 10;
		System.out.println("\t#"+Thread.currentThread().getName()+" got count from " + count);
		while(count > 0)
		{
			System.out.println("#"+Thread.currentThread().getName()+" : "+ count--);
		}
		System.out.println("#"+Thread.currentThread().getName()+" : exiting "+ count--);
	}
	public static void main(String[] args)
	{
		ThreadFromRunnable tr = new ThreadFromRunnable();
		Thread thread = new Thread(tr);
		Thread thread2 = new Thread(tr);
		
		thread.start();
		thread2.start();
	}

}

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()方法。

public class ThreadExtendsThread extends Thread {
	//static int count =10;
	public void run()
	{
		int count =10;
		System.out.println("\t#"+Thread.currentThread().getName()+" got count from " + count);
		while(count > 0)
		{
			System.out.println("{1}quot;+this.getName()+" : "+count--);
		}
		System.out.println("{1}quot;+this.getName()+" : existing count=" + count);
	}
	
	public static void main(String[] args)
	{
		ThreadExtendsThread thread = new ThreadExtendsThread();
		ThreadExtendsThread thread2 = new ThreadExtendsThread();
		thread.start();
		thread2.start();
	}
}
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的解釋:

The Runnable interface 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,Runnable is implemented by classThread. Being active simply means that a thread has been started and has not yet been stopped.

In addition, Runnable provides the means for a class to be active while not subclassingThread. A class that implementsRunnable can run without subclassingThread by instantiating aThread instance and passing itself in as the target. In most cases, theRunnable interface should be used if you are only planning to override therun() method and no otherThread methods. 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()方法。


原文引自 http://software.intel.com/zh-cn/blogs/2011/11/16/java-12/?cid=sw:prccsdn2063 稍有更改。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章