Java併發和多執行緒1:併發框架基本示例

小雷FansUnion發表於2015-12-30

Executor框架是指java 5中引入的一系列併發庫中與executor相關的一些功能類,其中包括ThreadPool,Executor,Executors,ExecutorService,CompletionService,Future,Callable等。


併發程式設計的一種程式設計方式是把任務拆分為一系列的小任務,即Runnable,然後在提交給一個Executor執行,Executor.execute(Runnalbe) 。Executor在執行時使用內部的執行緒池完成操作。
一、建立執行緒池
Executors類,提供了一系列工廠方法用於創先執行緒池,返回的執行緒池都實現了ExecutorService介面。
public static ExecutorService newFixedThreadPool(int nThreads)
建立固定數目執行緒的執行緒池。
public static ExecutorService newCachedThreadPool()
建立一個可快取的執行緒池,呼叫execute 將重用以前構造的執行緒(如果執行緒可用)。如果現有執行緒沒有可用的,則建立一個新執行緒並新增到池中。終止並從快取中移除那些已有 60 秒鐘未被使用的執行緒。
public static ExecutorService newSingleThreadExecutor()
建立一個單執行緒化的Executor。
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)
建立一個支援定時及週期性的任務執行的執行緒池,多數情況下可用來替代Timer類。


二、ExecutorService與生命週期
ExecutorService擴充套件了Executor並新增了一些生命週期管理的方法。一個Executor的生命週期有三種狀態,執行 ,關閉 ,終止 。Executor建立時處於執行狀態。當呼叫ExecutorService.shutdown()後,處於關閉狀態,isShutdown()方法返回true。
這時,不應該再向Executor中新增任務,所有已新增的任務執行完畢後,Executor處於終止狀態,isTerminated()返回true。
如果Executor處於關閉狀態,往Executor提交任務會丟擲unchecked exception RejectedExecutionException。


三、使用Callable,Future返回結果
Future<V>代表一個非同步執行的操作,通過get()方法可以獲得操作的結果,如果非同步操作還沒有完成,則,get()會使當前執行緒阻塞。FutureTask<V>實現了Future<V>和Runable<V>。Callable代表一個有返回值得操作。


ExecutoreService提供了submit()方法,傳遞一個Callable,或Runnable,返回Future。如果Executor後臺執行緒池還沒有完成Callable的計算,這呼叫返回Future物件的get()方法,會阻塞直到計算完成。


四、程式碼示例
package cn.fansunion.executorframework;


import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
import java.util.concurrent.RejectedExecutionException;
//併發框架幾個例子演示
public class ExecutorFrameworkDemo {


	public static Runnable task = new Runnable() {
		@Override
		public void run() {
			System.out.println("Execute a task");
		}
	};


	// 只使用1個工作執行緒,執行任務
	public static void singleThreadExecutor() {
		Executor executor = Executors.newSingleThreadExecutor();
		executor.execute(task);
	}


	// 擁有固定執行緒數目的執行緒池
	public static void fixedThreadPool() {
		Executor executor = Executors.newFixedThreadPool(10);
		executor.execute(task);
	}


	// 一個Executor的生命週期有三種狀態,執行 ,關閉 ,終止
	public static void executorLifeCycle() {
		ExecutorService executorService = Executors.newScheduledThreadPool(10);
		if (!executorService.isShutdown()) {
			try {
				executorService.execute(task);
			} catch (RejectedExecutionException e) {
				e.printStackTrace();
			}
		}
		executorService.shutdown();
	}


	// Future<V>代表一個非同步執行的操作,通過get()方法可以獲得操作的結果.
	// 如果非同步操作還沒有完成,則get()會使當前執行緒阻塞。
	// FutureTask<V>實現了Future<V>和Runable<V>。
	// Callable代表一個有返回值得操作。
	private static void futureCalable() {
		Callable<Integer> func = new Callable<Integer>() {
			public Integer call() throws Exception {
				System.out.println("inside callable");
				Thread.sleep(1000);
				Integer n = new Integer(8);
				return n;
			}
		};
		FutureTask<Integer> futureTask = new FutureTask<Integer>(func);
		Thread newThread = new Thread(futureTask);
		newThread.start();


		try {
			System.out.println("blocking here");
			Integer result = futureTask.get();
			System.out.println(result);
		} catch (InterruptedException ignored) {
		} catch (ExecutionException ignored) {
		}
	}


	public static void main(String[] args) {
		singleThreadExecutor();
		fixedThreadPool();
		executorLifeCycle();
		futureCalable();
	}
}



更多程式碼示例:
http://git.oschina.net/fansunion/Concurrent(逐步更新中)


參考資料:
java併發程式設計-Executor框架
http://www.iteye.com/topic/366591

相關文章