Future介面定義有get()方法以及isDone()方法,其目的就是在呼叫get()時看看能不能拿到執行緒跑好回傳的結果,倘若還沒做完程式就會阻斷直到做完為止;isDone()則是先試探看看執行緒是不是已經做完了,做完就回傳true,還沒做完就回傳false。
如果有觀念很強的人可能會覺得怪怪的,因為Runnable的run()方法是void呀?那我們要怎麼知道執行緒有沒有做完事情?
答案是Future的實作類別FutureTask的建構式有重載(overload)兩種:
FutureTask(Runnable runnable, V result)
FutureTask(Callable callable)
如果我們是丟Runnable進去,那我們可以再指派一個某種類別的result來當作get()回傳的結果。
現在我們有個新的問題了:Callable是什麼東西?
誠如剛剛我們所提到的,Future是在執行緒完成工作後會回傳一個結果的行為,為了補足Runnable沒有回傳值的特性,官方就多定義了一個叫做Callable的介面:
package java.util.concurrent;
public interface Callable<V> {
V call() throws Exception;
}
其實Callable和Runnable是幾乎同樣的概念,目的都是為了定義執行緒的任務,不過Callable的call()方法有回傳值,並且可以拋出受檢例外(checked exception)。
談到這邊就不得不談談ExecutorService了,因為ExecutorService除了官方幫我們覆寫好的execute方法外,其本身也有類似Thread的start()的方法,叫做submit(Callable task),並且會回傳Future型別的物件回來:
public static void main(String[] args) throws Exception{
ExecuteService service = Executors.newCacheThreadPool();
Future futureTask = service.submit(() -> dosomething());
while(!futureTask.isDone()){
do other things......
}
System.out.println("Result = " + futureTask.get());
}