1. 程式人生 > >Java實現多執行緒的方法

Java實現多執行緒的方法

java實現多執行緒的方式有三種:

1、繼承Thread類,重寫該類的run方法(Thread類實現了Runnable介面)

public class TestThread  extends Thread{

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		TestThread thread = new TestThread();
		thread.start();
	}
	
	public void run(){
		System.out.print("Thread is running");
	}

}

2、實現Runnable介面,實現介面中的run方法

public class TestThread  implements Runnable{

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Thread thread = new Thread(new TestThread());
		thread.start();
	}
	
	public void run(){
		System.out.print("Thread is running");
	}

}

3、實現Callable介面,實現call方法

public class TestThread  implements Callable{

	public static void main(String[] args) throws InterruptedException, ExecutionException {
		FutureTask task = new FutureTask(new TestThread());
		Thread thread = new Thread(task);
		thread.start();
		System.out.print(task.get());
	}
	
	public String call(){
		return "Thread is running";
	}

}

三者有何異同呢?我們來逐一比較:

1、首先我們都知道java類只能繼承一個父類,但可以實現多個介面,因此對比繼承Thread類,實現Runnable方法的同時還能繼承我們需要的父類,顯然這種方式更具有拓展性,且我們可以通過實現Runnable將執行緒任務的封裝,交由多個執行緒一起執行

2、實現Callable方法相比於前兩種方式,他需要實現call方法,且該方法有返回值,適合需要執行緒執行完之後返回結果的情況。例如我們有時候主執行緒想要做某一步操作,但是不必馬上知道這個操作的結果,也不想在這個操作上進行等待,那可以new一個新執行緒,然後實現callable介面,讓一個非同步子執行緒去完成這個操作,然後主執行緒可以繼續去做其他事情,等到需要用到這個操作返回結果的時候,就可以用fatureTaskd的get方法獲取返回值。值得注意的是,如果非同步子執行緒暫未執行完畢,get方法會一直阻塞直到拿到返回結果,當然,我們也可以選擇使用get(long timeout,TimeUnit unit)來實現超時等待,若超過等待時間則不再阻塞,直接返回;future在NIO實現的netty中有廣泛應用

3、實現callable介面的執行緒任務是可以通過futureTask的cancel方法進行取消的


那麼,我們在什麼時候需要用到多執行緒呢?

1、在硬體條件足夠好的情況下,使用多執行緒增加任務處理速度;例如多核CPU系統,批量處理系統利用多執行緒加快任務處理速度;

2、在許多IO等待的場景下,若使用單執行緒則當IO阻塞時執行緒無法處理其他事物,導致卡死,或者執行緒出現異常中斷後,導致功能不可用,此時也可以使用多執行緒

3、同步轉非同步場景下,我們需要使用一個子執行緒去進行某種操作,主執行緒繼續往下執行或直接返回,減少響應等待的場景

是不是多執行緒一定比單執行緒好呢?

1、在單核CPU的物理機上,多執行緒上下文之間的頻繁切換是很耗費cpu資源的,此時單執行緒是要比多執行緒快的;

2、執行緒的頻繁建立、銷燬也是消耗CPU效能和記憶體的,因此一般採用執行緒池管理