背景
多核處理器現在已廣泛應用。由於進程的線程可以在多個內核上並行執行,因此多核處理器為並行(並發)編程打開了一扇扇新的大門。為實現應用程序的最大性能,一項重要的技術就是將密集型任務拆分成可以並行執行的若干小塊,以便最大程度利用計算能力。
- 傳統上,處理並行(並發)編程一直很困難,因為您不得不處理線程同步和共享數據的問題。
- Java SE 5 及后來的 Java SE 6 引入了一組程序包,可以提供強大的並發構建塊。
- Java SE 7 通過添加並行支持進一步增強了這些構建塊。
- Java SE 8 增加了一個包含 50 個方法左右的類 CompletableFuture,它提供了非常強大的 Future 的擴展功能,可以幫助我們簡化異步編程的復雜性,並且提供了函數式編程的能力,可以通過回調的方式處理計算結果,也提供了轉換和組合 CompletableFuture 的方法。
Thread 類 & Runnable 接口
傳統通過創建多線程實現並行(並發)編程
- 繼承 Thread 類
- 實現 Runnable 接口
但這兩種方式創建的線程是屬於”三無產品“:沒有參數,沒有返回值,沒辦法拋出異常
ExecutorService、Callable、Future
ExecutorService、Callable、Future三個接口實際上都是屬於Executor框架。返回結果的線程是在JDK1.5中引入的新特征,有了這種特征就不需要再為了得到返回值而大費周折了。而且自己實現了也可能漏洞百出。
可返回值的任務必須實現Callable接口。類似的,無返回值的任務必須實現Runnable接口。
執行Callable任務后,可以獲取一個Future的對象,在該對象上調用get就可以獲取到Callable任務返回的Object了。
注意:get方法是阻塞的,即:線程無返回結果,get方法會一直等待。
再結合線程池接口ExecutorService就可以實現傳說中有返回結果的多線程了。
Future 的特性和 Javascript 的 Promise 是類似的,私下開玩笑通常將其比喻成男朋友的承諾
回歸到Java,我們從 JDK 的演變歷史,談及 Callable 的誕生,它彌補了 Runnable 沒有返回值的空缺,通過簡單的 demo 了解 Callable 與 Future 的使用。 FutureTask 又是 Future接口的核心實現類
CompletableFuture
CompletableFuture就為我們提供了異步函數式編程,CompletableFuture提供了非常強大的Future的擴展功能,可以幫助我們簡化異步編程的復雜性,提供了函數式編程的能力,可以通過回調的方式處理計算結果,並且提供了轉換和組合CompletableFuture的方法。下次重點學些下CompletableFuture的用法
parallelStream
Java8的paralleStream用fork/join框架提供了並發執行能力