1. 程式人生 > >Java自帶的執行緒池Executors.newFixedThreadPool

Java自帶的執行緒池Executors.newFixedThreadPool

  執行緒池的基本思想還是一種物件池的思想,開闢一塊記憶體空間,裡面存放了眾多(未死亡)的執行緒,池中執行緒執行排程由池管理器來處理。當有執行緒任務時,從池中取一個,執行完成後執行緒物件歸池,這樣可以避免反覆建立執行緒物件所帶來的效能開銷,節省了系統的資源。 

  在Java5之前,要實現一個執行緒池是相當有難度的,現在Java5為我們做好了一切,我們只需要按照提供的API來使用,即可享受執行緒池帶來的極大便利。 

  Java5的執行緒池分好多種:具體的可以分為兩類,固定尺寸的執行緒池、可變尺寸連線池。 

  在使用執行緒池之前,必須知道如何去建立一個執行緒池,在Java5中,需要了解的是java.util.concurrent.Executors類的API,這個類提供大量建立連線池的靜態方法,是必須掌握的。

一、固定大小的執行緒池,newFixedThreadPool:

class TestThread extends Thread {

	private String flag;

	public TestThread(String flag) {
		this.flag = flag;
	}

	@Override
	public void run() {
		System.out.println(Thread.currentThread().getName() + "正在執行。。。" + flag);
	}
}
	@Test
	public void fixedThreadPoolTest() {

		// 建立一個可重用固定執行緒數的執行緒池
		ExecutorService pool = Executors.newFixedThreadPool(5);
		// 建立執行緒
		Thread t1 = new TestThread("111");
		Thread t2 = new TestThread("222");
		Thread t3 = new TestThread("333");
		Thread t4 = new TestThread("444");
		Thread t5 = new TestThread("555");

		// 將執行緒放入池中進行執行
		pool.execute(t1);
		pool.execute(t2);
		pool.execute(t3);
		pool.execute(t4);
		pool.execute(t5);

		// 關閉執行緒池
		pool.shutdown();
	}
輸出結果:
pool-1-thread-1正在執行。。。111
pool-1-thread-3正在執行。。。333
pool-1-thread-2正在執行。。。222
pool-1-thread-4正在執行。。。444
pool-1-thread-5正在執行。。。555
改變ExecutorService pool = Executors.newFixedThreadPool(5)中的引數:ExecutorService pool = Executors.newFixedThreadPool(2),輸出結果是:
pool-1-thread-1正在執行。。。111
pool-1-thread-2正在執行。。。222
pool-1-thread-2正在執行。。。333
pool-1-thread-1正在執行。。。444
pool-1-thread-2正在執行。。。555
從以上結果可以看出,newFixedThreadPool的引數指定了可以執行的執行緒的最大數目,超過這個數目的執行緒加進去以後,不會立即執行,而是被放入任務佇列中等待執行。其次,加入執行緒池的執行緒屬於託管狀態,執行緒的執行不受加入順序的影響。

二、單任務執行緒池,newSingleThreadExecutor:

僅僅是把上述程式碼中的ExecutorService pool = Executors.newFixedThreadPool(2)改為ExecutorService pool = Executors.newSingleThreadExecutor();

	@Test
	public void singleThreadPoolTest() {

		// 建立一個單任務執行緒池
		ExecutorService pool = Executors.newSingleThreadExecutor();
		// 建立執行緒
		Thread t1 = new TestThread("111");
		Thread t2 = new TestThread("222");
		Thread t3 = new TestThread("333");
		Thread t4 = new TestThread("444");
		Thread t5 = new TestThread("555");

		// 將執行緒放入池中進行執行
		pool.execute(t1);
		pool.execute(t2);
		pool.execute(t3);
		pool.execute(t4);
		pool.execute(t5);

		// 關閉執行緒池
		pool.shutdown();
	}
輸出結果:
pool-1-thread-1正在執行。。。111
pool-1-thread-1正在執行。。。222
pool-1-thread-1正在執行。。。333
pool-1-thread-1正在執行。。。444
pool-1-thread-1正在執行。。。555
可以看出,每次呼叫execute方法,其實最後都是呼叫了thread-1的run方法。

也可以這樣使用

	@Test
	public void easyMethod() {

		ExecutorService pool = Executors.newFixedThreadPool(2);

		pool.execute(new Runnable() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				System.out.println("execute method1");
			}
		});

		pool.execute(new Runnable() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				System.out.println("execute method2");
			}
		});

		pool.shutdown();
	}