View a markdown version of this page

异步编程 - Amazon SDK for Java 1.x
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

Amazon SDK for Java 1.x于2025年12月31日达到支撑终止状态。我们建议您迁移到 Amazon SDK for Java 2.x 以继续获得新功能、可用性改进和安全更新。

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

异步编程

您可以使用同步异步方法来调用对 Amazon 服务的操作。同步方法会阻止执行您的线程,直到客户端接收到服务的响应。异步方法会立即返回,并控制调用的线程,而不必等待响应。

由于异步方法在收到响应之前返回,所以需要通过某种方法在响应准备就绪时接收响应。 Amazon SDK for Java 提供了两种方法:F uture 对象回调方法

Java Futures

中的异步方法 Amazon SDK for Java 返回一个 F ut ure 对象,该对象包含将来异步操作的结果。

调用 Future isDone() 方法,确定该服务是否已提供响应对象。当响应准备好时,可以通过调用 Future get() 方法来获取响应对象。在应用程序继续处理其他任务时,可使用该机制定期轮询异步操作的结果。

以下是一个异步操作的示例,该异步操作调用 Lambda 函数,接收Future可以容纳InvokeResult对象的函数。InvokeResult 对象仅在 isDone()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 对象即可确定请求是否已完成。相反,您的代码能够立即开始其下一个活动,并由开发工具包在适当时调用处理程序。

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实现。 Long-running 或者在处理程序方法中阻塞代码可能会导致异步客户端使用的线程池争用,并可能阻止客户端执行请求。如果需要从回调开始一种长期运行的任务,请在新的线程或应用程序托管的线程池中让回调运行其任务。

线程池配置

中的异步客户端 Amazon SDK for Java 提供了一个适用于大多数应用程序的默认线程池。您可以实现自定义ExecutorService并将其传递给 Amazon SDK for Java 异步客户端,以便更好地控制线程池的管理方式。

例如,您可以提供一个ExecutorService实现,该实现使用自定义ThreadFactory来控制池中线程的命名方式,或者记录有关线程使用情况的其他信息。

异步访问

SDK 中的TransferManager类为使用提供了异步支持 Amazon S3。 TransferManager管理异步上传和下载,提供详细的传输进度报告,并支持对不同事件的回调。