1. 程式人生 > >Java筆記-多執行緒之執行緒池

Java筆記-多執行緒之執行緒池

介紹

在前面的文章中,我們使用執行緒的時候就去建立一個執行緒,這樣實現起來非常簡便,但是就會有一個問題:

程式啟動一個新執行緒成本是比較高的,因為它涉及到要與作業系統進行互動。而使用執行緒池可以很好的提高效能,尤其是當程式中要建立大量生存期很短的執行緒時,更應該考慮使用執行緒池。

執行緒池裡的每一個執行緒程式碼結束後,並不會死亡,而是再次回到執行緒池中成為空閒狀態,等待下一個物件來使用。

在JDK5之前,我們必須手動實現自己的執行緒池,從JDK5開始,Java內建支援執行緒池

Executor工廠類

JDK5新增了一個Executors工廠類來產生執行緒池,有如下幾個方法:

1.public static ExecutorService newCachedThreadPool()


建立一個具有快取功能的執行緒池。

2.public static ExecutorService newFixedThreadPool(int nThreads)
建立一個可重用的,具有固定執行緒數的執行緒池。

3.public static ExecutorService newSingleThreadExecutor()
建立一個只有單執行緒的執行緒池,相當於上個方法(newFixedThreadPool)的引數nThreads等於1。

這些方法的返回值是ExecutorService物件,該物件表示一個執行緒池,可以執行Runnable物件或者Callable物件代表的執行緒。它提供瞭如下方法:

1.Future<?> submit(Runnable task)

2.<T> Future<T> submit(Callable<T> task)

Thread子類執行緒池程式碼演示

public class Test {
	public static void main(String[] args) {
		ExecutorService pool = Executors.newFixedThreadPool(2);
		pool.submit(new MyTh("貂蟬"));
		pool.submit(new MyTh("大喬"));
pool.submit(new MyTh("小喬")); pool.submit(new MyTh("黃月英")); pool.submit(new MyTh("孫尚香")); //執行緒池不是執行緒執行結束就終止,而是必須手動終止! pool.shutdown(); } } class MyTh extends Thread { int num = 0; public MyTh(String name) { super(name); } @Override public void run() { while (num < 50) { try { sleep(50); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(getName() + "--->" + (num++)); } } }

Runnable介面執行緒池程式碼演示

public class Test {
	public static void main(String[] args) {
		ExecutorService pool = Executors.newFixedThreadPool(2);
		pool.submit(new MyTh());
		pool.submit(new MyTh());
		pool.submit(new MyTh());
		pool.submit(new MyTh());
		pool.submit(new MyTh());
		// 執行緒池不是執行緒執行結束就終止,而是必須手動終止!
		pool.shutdown();
	}
}

class MyTh implements Runnable {
	int num = 0;

	@Override
	public void run() {
		while (num < 50) {
			try {
				Thread.sleep(50);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName() + "--->" + (num++));
		}
	}
}

Callable介面執行緒池程式碼演示

是一個子執行緒,但是不能直接執行,只能在執行緒池中使用!

public class Test {
	public static void main(String[] args) throws InterruptedException, ExecutionException {
		ExecutorService pool = Executors.newFixedThreadPool(2);
		Future<String> s1 = pool.submit(new MyTh());
		Future<String> s2 = pool.submit(new MyTh());
		Future<String> s3 = pool.submit(new MyTh());
		// 執行緒池不是執行緒執行結束就終止,而是必須手動終止!
		pool.shutdown();
		// Future物件只能通過get()方法獲取到值
		System.out.println(s1.get());
		System.out.println(s2.get());
		System.out.println(s3.get());
	}
}

class MyTh implements Callable<String> {
	int num = 0;

	@Override
	public String call() throws Exception {
		while (num < 50) {
			try {
				Thread.sleep(50);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName() + "--->" + (num++));
		}
		return "Callable執行結束";
	}
}