1. 程式人生 > >Java中的 FutureTask的示例與Runnable 區別

Java中的 FutureTask的示例與Runnable 區別

Java中存在Runnable、Callable、Future、FutureTask這幾個與執行緒相關的類或者介面,在Java中也是比較重要的幾個概念,我們通過下面的簡單示例來了解一下它們的作用於區別。

 package demo7;

import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;

/**
 * 
 * @author mrsimple
 *
 */
public class RunnableFutureTask {

	/**
	 * ExecutorService
	 */
	static ExecutorService mExecutor = Executors.newSingleThreadExecutor();

	/**
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		runnableDemo();
		futureDemo();
	}

	/**
	 * runnable, 無返回值
	 */
	static void runnableDemo() {

		new Thread(new Runnable() {

			@Override
			public void run() {
				System.out.println("runnable demo : " + fibc(20));
			}
		}).start();
	}

	/**
	 * <pre>
	 * 其中,Runnable實現的是void run()方法,無返回值;Callable實現的是 V call()方法,並且可以返回執行結果。
	 * 其中,Runnable可以提交給Thread來包裝下,直接啟動一個執行緒來執行,
	 * 而Callable則一般都是提交給ExecuteService來執行。
	 * </pre>
	 */
	static void futureDemo() {
		try {
			/**
			 * 提交runnable則沒有返回值, future沒有資料
			 */
			Future<?> result = mExecutor.submit(new Runnable() {

				@Override
				public void run() {
					fibc(20);
				}
			});

			System.out.println("future result from runnable : " + result.get());

			/**
			 * 提交Callable, 有返回值, future中能夠獲取返回值
			 */
			Future<Integer> result2 = mExecutor.submit(new Callable<Integer>() {
				@Override
				public Integer call() throws Exception {
					return fibc(20);
				}
			});

			System.out.println("future result from callable : " + result2.get());

			/**
			 * <pre>
			 * FutureTask則是一個RunnableFuture<V>,即實現了Runnbale又實現了Futrue<V>這兩個介面,
			 * 另外它還可以包裝Runnable(實際上會轉換為Callable)和Callable<V>,
			 * 所以一般來講是一個符合體了,它可以通過Thread包裝來直接執行,也可以提交給ExecuteService來執行,
			 * 並且還可以通過v get()返回執行結果,線上程體沒有執行完成的時候,主執行緒一直阻塞等待,執行完則直接返回結果。
			 * </pre>
			 */
			FutureTask<Integer> futureTask = new FutureTask<Integer>(
					new Callable<Integer>() {
						@Override
						public Integer call() throws Exception {
							return fibc(20);
						}
					});
			
			// 提交futureTask
			mExecutor.submit(futureTask) ;
			System.out.println("future result from futureTask : "+ futureTask.get());
			
			System.out.println("ExecutorService is shutdown ... ");
			mExecutor.shutdown();

		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (ExecutionException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 效率底下的斐波那契數列, 耗時的操作
	 * 
	 * @param num
	 * @return
	 * @throws InterruptedException 
	 */
	static int fibc(int num){
		if (num == 0) {
			return 0;
		}
		if (num == 1) {
			return 1;
		}
		return fibc(num - 1) + fibc(num - 2);
	}

}