在Java中使用Callable和Future
最近,我們正在開發一個監控儀表板,我們想要ping幾個第三方伺服器,只是為了檢查它們的可用性,或者我們想要呼叫健康檢查。
我們正在對伺服器進行一系列api呼叫,這些伺服器的IP,使用者名稱和密碼被外部化為環境變數。
然後是我們的負載均衡器丟擲HTTP 504(閘道器超時)的挑戰,因為這些請求花了很多時間來返回結果。
因此,我們繼續使用Callable和Future同時進行這些呼叫以減少所需的時間。
在開發多執行緒應用程式的傳統方式中,我們建立執行緒併為其提供Runnable任務。Callable與Runnable非常相似,它有一個細微的區別,它可以返回結果或丟擲異常,而Runnable的run方法的返回型別為void。
Runnable runnable = new Runnable() { @Override public void run() { // this can neither return the result nor throw an exception } } |
但是,Callable可以返回任務的結果並且可以丟擲異常。您也可以指定結果型別。為簡單起見,我把它作為String,但只要call()方法返回它,它就可以是任何複雜的物件。
Callable<String> callable = new Callable<String>() { @Override public String call() throws Exception { return "this can return output OR can throw Exception"; } }; |
既然您有Callable或任務,您需要能夠執行該任務以獲得輸出。您可以使用ExecutorService使用它的submit()方法執行任務,或使用invokeAll()執行多個任務 ,您可以在其中提交可呼叫任務的集合。
現在是有趣的部分,submit()的返回型別是Future <T>,其中T是輸出(String,如上例所示),invokeAll()的返回型別是List <Future <T >>
Future表示非同步計算的結果。Java提供了檢查計算是否完成,等待它完成或從中檢索結果的方法。(它非常類似於javascript承諾,如果這使它易於理解)。因此,為了獲得未來的結果,我們只需要呼叫get()就可以了
ExecutorService executorService = Executors.newFixedThreadPool(10); // callable from above code Future<String> future = executorService.submit(callable); String output = future.get(); |
下面是完整程式碼:
public class HealthCheckService { private HttpHandler httpHandler; private Config config; private ExecutorService executor; public HealthCheckService(HttpHandler httpHandler,Config config) { this.httpHandler = httpHandler; this.configuration = configuration; int size = config.servers.size(); this.executor = Executors.newFixedThreadPool(size); } public List<HealthCheckResult> getHealthCheck() throws Exception { List<Callable<HealthCheck>> tasks = prepareTasks(config.uri); List<Future<HealthCheck>> futures = executor.invokeAll(tasks); List<HealthCheck> output = new ArrayList<>(); for (Future<HealthCheckResult> future: futures) { output.add(future.get()); } return output; } private List<Callable<HealthCheck>> prepareTasks(String api) { List<Callable<HealthCheckResult>> tasks = new ArrayList(); for (String server: config.servers) { tasks.add(() -> httpHandler.getStatus(api)); } return tasks; } } |
原始碼見:Github
相關文章
- Java多執行緒-Callable和FutureJava執行緒
- 併發-9-Callable和Future
- Java多執行緒之Callable,Future,FutureTaskJava執行緒
- Future 和 FutureTask用於接收callable的返回值
- Runnable,Callable,Future關係淺析
- 大話Android多執行緒(四) Callable、Future和FutureTaskAndroid執行緒
- 搞懂Runnable Callable Future FutureTask 及應用
- PHP 中`Closure`和`Callable`的區別以及在 Redis 訂閱方法中的使用PHPRedis
- Akka系列(五):Java和Scala中的FutureJava
- (十三) 說一下runnable 和 callable 有什麼區別?Future是什麼?
- Java中「Future」介面詳解Java
- Dart中的Future使用Dart
- 執行緒執行 之 Runnable Callable Future ,FutureTask ExcutorService概覽執行緒
- Java併發程式設計-Future系列之Future的介紹和基本用法Java程式設計
- Java的Future介面Java
- future promise shared_future簡單使用Promise
- 在 Java 中如何使用 transientJava
- PHP Callback/Callable 型別使用PHP型別
- Future和CompletableFuture的理解
- 在Java中this關鍵字的使用Java
- Java併發程式設計非同步操作Future和FutureTaskJava程式設計非同步
- 正規表示式在Java中的使用Java
- flutter實戰5:非同步async、await和Future的使用技巧Flutter非同步AI
- 在Linux中,如何配置和使用Xen?Linux
- Django程式碼中的TypeError 'float' object is not callableDjangoErrorObject
- Callable(簡單)
- 使用 Java 在Excel中建立下拉選單JavaExcel
- Redis的安裝及在Java中的使用RedisJava
- Java非同步之《我call(),Future在哪裡》Java非同步
- Java多執行緒帶返回值的Callable介面Java執行緒
- 在.NET 6中使用DateOnly和TimeOnly
- Java 11:在Java中處理HTTP和WebSocket的新方法!JavaHTTPWeb
- Hanlp在java中文分詞中的使用介紹HanLPJava中文分詞
- Java / JavaScript在TensorFlow中的入門使用指南JavaScript
- 在ASP.Net Core和Java中配置金鑰ASP.NETJava
- 在Java中是如何定義和宣告介面的?Java
- JUC之Callable介面回顧和JUC輔助類
- C++,std::shared_future的使用C++