1. 程式人生 > >建立執行緒的幾種方法及比較

建立執行緒的幾種方法及比較

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

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

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

public class ThreadTest extends Thread{

	public void run(){
		for(int i=0;i<=10;i++){
			System.out.println(i);
		}		
	}
	
	public static void main(String[] args) {
		ThreadTest thread1=new ThreadTest();
		ThreadTest thread2=new ThreadTest();
		thread1.start();
		thread2.start();
	}
}

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

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

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

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

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

public class ThreadTest implements Runnable{
	
	@Override
	public void run() {
		for(int i=0;i<=10;i++){
			System.out.println(i);
		}	
	}
	public static void main(String[] args) {
		ThreadTest threadTest=new ThreadTest();
		Thread theard=new Thread(threadTest);
		theard.start();
	}
}

3.通過Callable和Future建立執行緒

(1)建立Callable介面的實現類,並實現call()方法,該call()方法將作為執行緒執行體,並且有返回值。

(2)建立Callable實現類的例項,使用FutureTask類來包裝Callable物件,該FutureTask物件封裝了該Callable物件的call()方法的返回值。

(3)使用FutureTask物件作為Thread物件的target建立並啟動新執行緒。

(4)呼叫FutureTask物件的get()方法來獲得子執行緒執行結束後的返回值

public class ThreadTest implements Callable<Integer>{

	@Override
	public Integer call() throws Exception {
		int count =0;
		for(int i=0;i<=10;i++){
			count=count+i;
		}
		return count;	
	}
	public static void main(String[] args) throws InterruptedException, ExecutionException {
		ThreadTest test=new ThreadTest();
		FutureTask<Integer> thread = new FutureTask<>(test);
		new Thread(thread,"有返回值的執行緒").start();  
		System.out.println(thread.get());
	}
	
}

         使用實現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.

採用實現Runnable、Callable介面的方式創見多執行緒時,優勢是:

執行緒類只是實現了Runnable介面或Callable介面,還可以繼承其他類。

在這種方式下,多個執行緒可以共享同一個target物件,所以非常適合多個相同執行緒來處理同一份資源的情況,從而可以將CPU、程式碼和資料分開,形成清晰的模型,較好地體現了面向物件的思想。

劣勢是:

程式設計稍微複雜,如果要訪問當前執行緒,則必須使用Thread.currentThread()方法。

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