教你如何判斷Java代碼中異步操作是否完成

1. 使用Future和Callable

Java中的Future接口定義了一種方式來表示異步操作的未來結(jié)果。我們可以使用Callable接口來定義異步任務(wù),它返回一個Future對象,我們可以利用Future對象的方法來檢查任務(wù)是否完成。 下面是一個例子:

javaCopy code

import java.util.concurrent.Callable;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.concurrent.Future;publicclass AsyncDemo {

? ? publicstaticvoid main(String[] args) throws Exception {

? ? ? ? ExecutorService executorService = Executors.newSingleThreadExecutor();

? ? ? ? // 定義異步任務(wù)Callable asyncTask = () -> {

? ? ? ? ? ? Thread.sleep(2000);// 模擬耗時操作return"Async task completed";

? ? ? ? };

? ? ? ? // 提交異步任務(wù)Future future = executorService.submit(asyncTask);

? ? ? ? // 判斷任務(wù)是否完成while(!future.isDone()) {

? ? ? ? ? ? System.out.println("Task not done yet...");

? ? ? ? ? ? Thread.sleep(500);

? ? ? ? }

? ? ? ? // 獲取結(jié)果String result = future.get();

? ? ? ? System.out.println(result);

? ? ? ? // 關(guān)閉線程池? ? ? ? executorService.shutdown();

? ? }

}

在上面的代碼中,我們創(chuàng)建了一個單線程的ExecutorService來執(zhí)行異步任務(wù)。我們使用submit方法提交異步任務(wù),并得到一個Future對象。然后,我們可以使用isDone()方法來判斷任務(wù)是否完成,如果任務(wù)沒有完成,則等待片刻后再次檢查。一旦任務(wù)完成,我們可以使用get()方法獲取任務(wù)的結(jié)果。

2. 使用CompletableFuture

自Java 8起,Java提供了CompletableFuture類來更加方便地處理異步操作。CompletableFuture是Future的一個實現(xiàn),同時也支持對未來結(jié)果的處理和組合。 下面是一個例子:

javaCopy code

import java.util.concurrent.CompletableFuture;

import java.util.concurrent.TimeUnit;publicclass AsyncDemo {

? ? publicstaticvoid main(String[] args) throws Exception {

? ? ? ? // 定義異步任務(wù)CompletableFuture future = CompletableFuture.supplyAsync(() -> {

? ? ? ? ? ? try {

? ? ? ? ? ? ? ? TimeUnit.SECONDS.sleep(2);// 模擬耗時操作}catch (InterruptedException e) {

? ? ? ? ? ? ? ? e.printStackTrace();

? ? ? ? ? ? }

? ? ? ? ? ? return"Async task completed";

? ? ? ? });

? ? ? ? // 判斷任務(wù)是否完成while(!future.isDone()) {

? ? ? ? ? ? System.out.println("Task not done yet...");

? ? ? ? ? ? TimeUnit.MILLISECONDS.sleep(500);

? ? ? ? }

? ? ? ? // 獲取結(jié)果String result = future.get();

? ? ? ? System.out.println(result);

? ? }

}

在上述代碼中,我們使用supplyAsync方法創(chuàng)建了一個CompletableFuture對象,并定義了異步任務(wù)。然后,我們可以使用isDone()方法來判斷任務(wù)是否完成。通過調(diào)用get()方法可以獲取最終的結(jié)果。

當(dāng)涉及到實際應(yīng)用場景時,異步操作的一個常見用例是在Web應(yīng)用中執(zhí)行并行的HTTP請求以提高性能。以下是一個示例代碼,展示了如何使用異步操作來執(zhí)行多個HTTP請求,并在所有請求完成后進行處理。

javaCopy code

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStreamReader;

import java.net.HttpURLConnection;

import java.net.URL;

import java.util.ArrayList;

import java.util.List;

import java.util.concurrent.*;publicclass AsyncHttpExample {

? ? publicstaticvoid main(String[] args) throws Exception {

? ? ? ? List> futures =newArrayList<>();


? ? ? ? ExecutorService executor = Executors.newFixedThreadPool(5);


? ? ? ? List urls = List.of(

? ? ? ? ? ? ? ? "https://www.example.com/api1",

? ? ? ? ? ? ? ? "https://www.example.com/api2",

? ? ? ? ? ? ? ? "https://www.example.com/api3"? ? ? ? );


? ? ? ? for (String url : urls) {

? ? ? ? ? ? Callable task = () -> {

? ? ? ? ? ? ? ? return performRequest(url);

? ? ? ? ? ? };


? ? ? ? ? ? Future future = executor.submit(task);

? ? ? ? ? ? futures.add(future);

? ? ? ? }


? ? ? ? executor.shutdown();


? ? ? ? for(Future future : futures) {

? ? ? ? ? ? try {

? ? ? ? ? ? ? ? String result = future.get();

? ? ? ? ? ? ? ? System.out.println("Received response: "+ result);

? ? ? ? ? ? } catch(InterruptedException | ExecutionException e) {

? ? ? ? ? ? ? ? e.printStackTrace();

? ? ? ? ? ? }

? ? ? ? }

? ? }


? ? privatestatic String performRequest(String url) throws IOException {

? ? ? ? HttpURLConnection connection =null;

? ? ? ? BufferedReader reader =null;

? ? ? ? StringBuilder response =new StringBuilder();


? ? ? ? try {

? ? ? ? ? ? URL requestUrl =new URL(url);

? ? ? ? ? ? connection = (HttpURLConnection) requestUrl.openConnection();

? ? ? ? ? ? connection.setRequestMethod("GET");


? ? ? ? ? ? reader =newBufferedReader(new InputStreamReader(connection.getInputStream()));

? ? ? ? ? ? String line;


? ? ? ? ? ? while((line = reader.readLine()) !=null) {

? ? ? ? ? ? ? ? response.append(line);

? ? ? ? ? ? }

? ? ? ? } finally {

? ? ? ? ? ? if(connection !=null) {

? ? ? ? ? ? ? ? connection.disconnect();

? ? ? ? ? ? }


? ? ? ? ? ? if(reader !=null) {

? ? ? ? ? ? ? ? reader.close();

? ? ? ? ? ? }

? ? ? ? }


? ? ? ? return response.toString();

? ? }

}

在這個示例中,我們創(chuàng)建了一個固定大小的線程池,并為每個URL創(chuàng)建了一個異步任務(wù)。每個任務(wù)在自己的線程中執(zhí)行HTTP請求,并返回響應(yīng)結(jié)果。我們使用Future來跟蹤每個任務(wù)的執(zhí)行狀態(tài)和結(jié)果。一旦所有任務(wù)都被提交,我們調(diào)用shutdown()方法關(guān)閉線程池,然后通過迭代每個Future對象,使用get()方法獲取任務(wù)的結(jié)果。最后,我們可以根據(jù)需要對結(jié)果進行進一步處理,這里只是簡單地打印出每個請求的響應(yīng)。

java.util.concurrent.Callable?是 Java 并發(fā)編程中的一個接口,它表示一個可調(diào)用的任務(wù),可以在計算中返回一個值。與?Runnable?接口不同,Callable?接口的?call()?方法可以返回一個結(jié)果,并且可以在執(zhí)行過程中拋出受檢異常。?Callable?接口定義了以下方法:

V call() throws Exception:執(zhí)行任務(wù)并返回結(jié)果。可以拋出受檢異常。

boolean equals(Object obj):比較該?Callable?與指定對象是否相等。

default <U> Callable<U> compose(Function<? super V, ? extends U> var1):將該?Callable?的結(jié)果應(yīng)用于給定函數(shù),并返回?Callable。

default <V2> Callable<V2> andThen(Function<? super V, ? extends V2> var1):將給定函數(shù)應(yīng)用于該?Callable?的結(jié)果,并返回新的?Callable。

default Predicate<V> isEqual(Object var1):返回謂詞,用于判斷對象是否與這個?Callable?的結(jié)果相等。

default Supplier<V> toSupplier():返回將該?Callable?的結(jié)果作為值的供應(yīng)商。 在實際應(yīng)用中,Callable?接口常常與?ExecutorService?結(jié)合使用,通過將?Callable?對象提交給線程池來執(zhí)行。線程池會返回一個?Future?對象,用于跟蹤任務(wù)的執(zhí)行狀態(tài)和獲取結(jié)果。 以下是一個示例代碼,展示了如何使用?Callable?接口:

javaCopy code

import java.util.concurrent.Callable;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.concurrent.Future;publicclass CallableExample {

? ? publicstaticvoid main(String[] args) throws Exception {

? ? ? ? Callable task = () -> {

? ? ? ? ? ? intsum =0;

? ? ? ? ? ? for(inti =1; i <=100; i++) {

? ? ? ? ? ? ? ? sum += i;

? ? ? ? ? ? }

? ? ? ? ? ? return sum;

? ? ? ? };


? ? ? ? ExecutorService executor = Executors.newSingleThreadExecutor();

? ? ? ? Future future = executor.submit(task);


? ? ? ? // 可以在此處執(zhí)行其他任務(wù)? ? ? ?

? ? ? ? Integer result = future.get();// 獲取任務(wù)的結(jié)果,會阻塞直到任務(wù)完成System.out.println("Sum: "+ result);


? ? ? ? executor.shutdown();

? ? }

}

散熱風(fēng)扇https://www.uv-semi.com/

深圳網(wǎng)站建設(shè)www.sz886.com

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容