非同步程式設計 - AWS SDK for Java 1.

我們宣布了即將推 end-of-support 出的 AWS SDK for Java (v1)。我們建議您移轉至 AWS SDK for Java v2。有關日期,其他詳細信息以及如何遷移的信息,請參閱鏈接的公告。

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

非同步程式設計

您可以使用同步非同步方法來呼叫 AWS 服務上的作業。同步方法會封鎖您的執行緒執行,直到用戶端收到服務的回應。非同步方法會立即傳回,將控制權回歸給呼叫端執行緒,無需等待回應。

由於非同步方法會在有可用回應之前傳回,您需要一個方法在回應準備好時取得回應。 AWS SDK for Java 提供了兩種方式:未來的對象回調方法

爪哇期貨

異步方法在 AWS SDK for Java 返回一個包含 future 異步操作結果的 Future 對象。

調用該FutureisDone()方法以查看服務是否提供了響應對象。當響應準備就緒時,您可以通過調用該Futureget()方法獲取響應對象。您可以使用此機制來定期輪詢非同步作業的結果,而您的應用程式會繼續處理其他項目。

下面是一個異步操作的例子,它調用一個 Lambda 函數,接收一個可Future以容納一個InvokeResult對象的。只有在是之後才會擷取InvokeResultisDone()true

import com.amazonaws.services.lambda.AWSLambdaAsyncClient; import com.amazonaws.services.lambda.model.InvokeRequest; import com.amazonaws.services.lambda.model.InvokeResult; import java.nio.ByteBuffer; import java.util.concurrent.Future; import java.util.concurrent.ExecutionException; public class InvokeLambdaFunctionAsync { public static void main(String[] args) { String function_name = "HelloFunction"; String function_input = "{\"who\":\"SDK for Java\"}"; AWSLambdaAsync lambda = AWSLambdaAsyncClientBuilder.defaultClient(); InvokeRequest req = new InvokeRequest() .withFunctionName(function_name) .withPayload(ByteBuffer.wrap(function_input.getBytes())); Future<InvokeResult> future_res = lambda.invokeAsync(req); System.out.print("Waiting for future"); while (future_res.isDone() == false) { System.out.print("."); try { Thread.sleep(1000); } catch (InterruptedException e) { System.err.println("\nThread.sleep() was interrupted!"); System.exit(1); } } try { InvokeResult res = future_res.get(); if (res.getStatusCode() == 200) { System.out.println("\nLambda function returned:"); ByteBuffer response_payload = res.getPayload(); System.out.println(new String(response_payload.array())); } else { System.out.format("Received a non-OK response from {AWS}: %d\n", res.getStatusCode()); } } catch (InterruptedException | ExecutionException e) { System.err.println(e.getMessage()); System.exit(1); } System.exit(0); } }

非同步回呼

除了使用 Java Future 物件監視非同步要求的狀態之外,SDK 也可讓您實作使用AsyncHandler介面的類別。 AsyncHandler根據要求完成的方式,提供兩種呼叫的方法:onSuccessonError

回調接口方法的主要優點是,它使您無需輪詢對Future象以了解請求何時完成。相反,您的代碼可以立即開始其下一個活動,並依靠 SDK 在正確的時間調用您的處理程序。

import com.amazonaws.services.lambda.AWSLambdaAsync; import com.amazonaws.services.lambda.AWSLambdaAsyncClientBuilder; import com.amazonaws.services.lambda.model.InvokeRequest; import com.amazonaws.services.lambda.model.InvokeResult; import com.amazonaws.handlers.AsyncHandler; import java.nio.ByteBuffer; import java.util.concurrent.Future; public class InvokeLambdaFunctionCallback { private class AsyncLambdaHandler implements AsyncHandler<InvokeRequest, InvokeResult> { public void onSuccess(InvokeRequest req, InvokeResult res) { System.out.println("\nLambda function returned:"); ByteBuffer response_payload = res.getPayload(); System.out.println(new String(response_payload.array())); System.exit(0); } public void onError(Exception e) { System.out.println(e.getMessage()); System.exit(1); } } public static void main(String[] args) { String function_name = "HelloFunction"; String function_input = "{\"who\":\"SDK for Java\"}"; AWSLambdaAsync lambda = AWSLambdaAsyncClientBuilder.defaultClient(); InvokeRequest req = new InvokeRequest() .withFunctionName(function_name) .withPayload(ByteBuffer.wrap(function_input.getBytes())); Future<InvokeResult> future_res = lambda.invokeAsync(req, new AsyncLambdaHandler()); System.out.print("Waiting for async callback"); while (!future_res.isDone() && !future_res.isCancelled()) { // perform some other tasks... try { Thread.sleep(1000); } catch (InterruptedException e) { System.err.println("Thread.sleep() was interrupted!"); System.exit(0); } System.out.print("."); } } }

最佳實務

回呼執行

您的AsyncHandler實作會在非同步用戶端所擁有的執行緒集區內執行。簡短,快速執行的代碼在您的AsyncHandler實現中是最合適的。處理常式方法中的長時間執行或封鎖程式碼可能會對非同步用戶端所使用的執行緒集區造成爭用,而且可能會阻止用戶端執行要求。如果您有需要從回調開始的長時間運行任務,請讓回調在新線程或應用程序管理的線程池中運行其任務。

執行緒集區組態

中的非同步用戶端 AWS SDK for Java 提供預設執行緒集區,該執行緒集區應適用於大多數應用程式 您可以實作自訂ExecutorService並將其傳遞給 AWS SDK for Java 非同步用戶端,以進一步控制執行緒集區的管理方式。

例如,您可以提供使用 Custom ThreadFactory來控制集區中執行緒的命名方式的ExecutorService實作,或記錄執行緒使用情況的其他相關資訊。

非同步存取

SDK 中的TransferManager類別為使用提供非同步支援 Amazon S3。 TransferManager管理異步上傳和下載,提供有關傳輸的詳細進度報告,並支持對不同事件的回調。