在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執行緒
- Java多執行緒——Callable、Future和FutureTaskJava執行緒
- Java併發程式設計:Callable、Future和FutureTaskJava程式設計
- Java併發之Executor + Callable + FutureJava
- Java多執行緒之Callable,Future,FutureTaskJava執行緒
- Runnable,Callable,Future關係淺析
- 搞懂Runnable Callable Future FutureTask 及應用
- 大話Android多執行緒(四) Callable、Future和FutureTaskAndroid執行緒
- Runnable、Callable、Executor、Future、FutureTask關係解讀
- Akka系列(五):Java和Scala中的FutureJava
- Akka 系列(五):Java 和 Scala 中的 FutureJava
- PHP 中`Closure`和`Callable`的區別以及在 Redis 訂閱方法中的使用PHPRedis
- Java多執行緒21:多執行緒下的其他元件之CyclicBarrier、Callable、Future和FutureTaskJava執行緒元件
- Java中「Future」介面詳解Java
- Dart中的Future使用Dart
- (十三) 說一下runnable 和 callable 有什麼區別?Future是什麼?
- 執行緒執行 之 Runnable Callable Future ,FutureTask ExcutorService概覽執行緒
- 【Akka】在併發程式中使用Future
- Java併發程式設計-Future系列之Future的介紹和基本用法Java程式設計
- Java的Future介面Java
- 在 Java 中如何使用 transientJava
- REST 在 Java 中的使用RESTJava
- future promise shared_future簡單使用Promise
- PHP Callback/Callable 型別使用PHP型別
- 在java中“equals”和“==”的區別Java
- 在Java中this關鍵字的使用Java
- Java併發程式設計非同步操作Future和FutureTaskJava程式設計非同步
- Future和CompletableFuture的理解
- 正規表示式在Java中的使用Java
- ThreadLocal在java web工程中的使用。threadJavaWeb
- 【Java】【轉】在命令列中編譯和執行javaJava命令列編譯
- Django程式碼中的TypeError 'float' object is not callableDjangoErrorObject
- Redis的安裝及在Java中的使用RedisJava
- java反射(3)在工廠模式中的使用Java反射模式
- Java Web之MySQL在專案中的使用JavaWebMySql
- 使用 Java 在Excel中建立下拉選單JavaExcel
- 在Linux中,如何配置和使用Xen?Linux
- flutter實戰5:非同步async、await和Future的使用技巧Flutter非同步AI