隨著CPU的核數的增加,非同步程式設計模型在併發領域中的得到了越來越多的應用,由於Scala是一門函式式語言,天然的支援非同步程式設計模型,今天主要來看一下Java和Scala中的Futrue,帶你走入非同步程式設計的大門。
Future
很多同學可能會有疑問,Futrue跟非同步程式設計有什麼關係?從Future的表面意思是未來,一個Future物件可以看出一個將來得到的結果,這就和非同步執行的概念很像,你只管自己去執行,只要將最終的結果傳達給我就行,執行緒不必一直暫停等待結果,可以在具體非同步任務執行的時候去執行其他操作,舉個例子:
我們現在在執行做飯這麼一個任務,它需要煮飯,燒菜,擺置餐具等操作,如果我們通過非同步這種概念去執行這個任務,比如煮飯可能需要比較久的時間,但煮飯這個過程又不需要我們管理,我們可以利用這段時間去燒菜,燒菜過程中也可能有空閒時間,我們可以去擺置餐具,當電飯鍋通知我們飯燒好了,菜也燒好了,最後我們就可以開始吃飯了,所以說,上面的“煮飯 -> 飯”,“燒菜 -> 菜”都可以看成一個Future的過程。
Java中的Future
在Java的早期版本中,我們不能得到執行緒的執行結果,不管是繼承Thread類還是實現Runnable介面,都無法獲取執行緒的執行結果,所以我們只能線上程執行的run方法裡去做相應的一些業務邏輯操作,但隨著Java5的釋出,它為了我們帶來了Callable和Future介面,我們可以利用這兩個介面的特性來獲取執行緒的執行結果。
Callable介面
通俗的講,Callable介面也是一個執行緒執行類介面,那麼它跟Runnable介面有什麼區別呢?我們先來看看它們兩個的定義:
1.Callable介面:
@FunctionalInterface
public interface Callable<V> {
/**
* Computes a result, or throws an exception if unable to do so.
*
* @return computed result
* @throws Exception if unable to compute a result
*/
V call() throws Exception;
}複製程式碼
2.Runnable介面:
@FunctionalInterface
public interface Runnable {
public abstract void run();
}複製程式碼
從上面的定義,我們可以看出,兩者最大的區別就是對應的執行方法是否有返回值。Callable介面中call方法具有返回值,這便是為什麼我們可以通過Callable介面來得到一個執行緒執行的返回值或者是異常資訊。
Future介面
上面說到既然Callable介面能返回執行緒執行的結果,那麼為什麼還需要Future介面呢?因為Callable介面執行的結果只是一個將來的結果值,我們若是需要得到具體的結果就必須利用Future介面,另外Callable介面需要委託ExecutorService的submit提交任務去執行,我們來看看它是如何定義的:
<T> Future<T> submit(Callable<T> task);
public <T> Future<T> submit(Callable<T> task) {
if (task == null) throw new NullPointerException();
RunnableFuture<T> ftask = newTaskFor(task);
execute(ftask);
return ftask;
}複製程式碼