2、為什么我們需要Callable接口
可以將任務(wù)分開多線程去做,并通過返回值的方式匯總到主線程,輸出結(jié)果。

Callable接口
3、注意點
3.1、futureTask.get():
如無必須,要放在最后,因為get()方法要求獲得Callable線程的返回值,如果沒有計算完成會導(dǎo)致堵塞,直到計算完成。
也就是說,調(diào)用get方法就需要得到結(jié)果,一旦有多個未知效率的FutureTask,如何安排其get方法的調(diào)用順序?qū)⒊蔀橐粋€問題。
package com.company;
import java.util.concurrent.*;
class MyThread2 implements Callable<Integer>
{
@Override
public Integer call() throws Exception {
System.out.println("task3 start");
//一個非常復(fù)雜耗時的運(yùn)算過程
try{TimeUnit.SECONDS.sleep(5);}catch (Exception e){e.printStackTrace();}
System.out.println("經(jīng)過了一個非常復(fù)雜耗時的運(yùn)算過程之后");
return 44;
}
}
public class CallableDemo {
public static void main(String[] args) throws ExecutionException, InterruptedException {
//task 1
int i = 10+1;
System.out.println("task 1:i = " + i);
//task 2
int j = 12-1;
System.out.println("task 2:j = " + j);
//task 3
//FutureTask實現(xiàn)了Runnable接口,同時提供了一個入?yún)镃allable的構(gòu)造方法
FutureTask<Integer> futureTask = new FutureTask<>(new MyThread2());
Thread t1 = new Thread(futureTask,"AAAA");
t1.start();
try{TimeUnit.SECONDS.sleep(1);}catch (Exception e){e.printStackTrace();}
//task 4
int x = 1;
System.out.println("task 4:x = " + x);
System.out.println("最終四個task運(yùn)算的結(jié)果是:" + (i+j+futureTask.get())*x);
}
}
while(!futureTask.isDone()){
}
int a = futureTask.get();
FutureTask
可取消的異步計算。 該類提供了一個Future的基本實現(xiàn),具有啟動和取消計算的方法,查詢計算是否完整,并檢索計算結(jié)果。 結(jié)果只能在計算完成后才能檢索; 如果計算尚未完成,則get方法將阻止。 一旦計算完成,則無法重新啟動或取消計算(除非使用runAndReset()調(diào)用[計算]。FutureTask可用于包裝Callable或Runnable對象。 因為FutureTask實現(xiàn)Runnable,一個FutureTask可以提交到一個Executor執(zhí)行。
除了作為獨(dú)立類之外,此類還提供了protected功能,在創(chuàng)建自定義任務(wù)類時可能很有用。
3.2、一旦計算完成,則無法重新啟動或取消計算(除非使用runAndReset()調(diào)用[計算]。
同一個計算過程只能有一個線程進(jìn)行運(yùn)算,其他線程不能再啟動這個計算。