Future和FutureTask的區別


java中有Future和FutureTask這兩個類

Future是一個接口,代表可以取消的任務,並可以獲得任務的執行結果

FutureTask 是基本的實現了Future和runnable接口
           實現runnable接口,說明可以把FutureTask實例傳入到Thread中,在一個新的線程中執行。
           實現Future接口,說明可以從FutureTask中通過get取到任務的返回結果,也可以取消任務執行(通過interreput中斷)

FutureTask可用於異步獲取執行結果或取消執行任務的場景。通過傳入Runnable或者Callable的任務給FutureTask,直接調用其run方法或者放入線程池執行,之后可以在外部通過FutureTask的get方法異步獲取執行結果,因此,FutureTask非常適合用於耗時的計算,主線程可以在完成自己的任務后,再去獲取結果。另外,FutureTask還可以確保即使調用了多次run方法,它都只會執行一次Runnable或者Callable任務,或者通過cancel取消FutureTask的執行等

1.FutureTask執行多任務計算的使用場景

利用FutureTask和ExecutorService,可以用多線程的方式提交計算任務,主線程繼續執行其他任務,當主線程需要子線程的計算結果時,在異步獲取子線程的執行結果。

package cn.zhm.day3;
 
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
 
public class FutureTaskForMultiCompute {
 
	public static void main(String[] args) throws InterruptedException,
			ExecutionException {
		FutureTaskForMultiCompute inst = new FutureTaskForMultiCompute();
		// 創建任務集合
		List<FutureTask<Integer>> taskList = new ArrayList<FutureTask<Integer>>();
		ExecutorService execut = Executors.newScheduledThreadPool(5);
		for (int i = 0; i < 10; i++) {
			// 傳入Callable對象創建FutureTask對象
			// inst.new ComputeTask(i, " "+i); 不太明白什么意思
			FutureTask<Integer> task = new FutureTask<Integer>(
					inst.new ComputeTask(i, "" + i));
			// 把多個future放在集合中
			taskList.add(task);
			// 提交給線程池執行任務,也可以通過exec.invokeAll(taskList)一次性提交所有任務;
			execut.submit(task);
			System.out.println("所有計算任務提交完畢, 主線程接着干其他事情!");
		}
		Integer result = 0;
		// 從future中取出值來
		for (FutureTask<Integer> future : taskList) {
			result = result + future.get();
		}
		// 打印求出來的值
		System.out.println("result=" + result);
	}
 
	public class ComputeTask implements Callable<Integer> {
		private Integer result = 0;
		private String taskName = "";
 
		ComputeTask(Integer result, String taskName) {
			this.result = result;
			this.taskName = taskName;
			System.out.println("生成子線程計算任務: " + taskName);
		}
 
		public String getTaskName() {
			return this.taskName;
		}
 
		@Override
		public Integer call() throws Exception {
			for (int i = 0; i < 10; i++) {
				result += i;
 
			}
			Thread.sleep(5000);
			System.out.println("子線程計算任務: " + taskName + " 執行完成!");
			return result;
		}
 
	}
}

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM