

 適用於 Java 的 AWS SDK 1.x 已於 2025 年 12 月 31 日end-of-support。我們建議您遷移至 [AWS SDK for Java 2.x](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/home.html)，以繼續接收新功能、可用性改善和安全性更新。

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

# 非同步程式設計
<a name="basics-async"></a>

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

由於非同步方法會在有可用回應之前傳回，您需要一個方法在回應準備好時取得回應。 適用於 Java 的 AWS SDK 提供兩種方式：*未來物件*和*回呼方法*。

## Java 未來
<a name="basics-async-future"></a>

中的非同步方法會 適用於 Java 的 AWS SDK 傳回[未來](https://docs.oracle.com/javase/8/docs/api/index.html?java/util/concurrent/Future.html)物件，其中包含*未來*非同步操作的結果。

呼叫 `Future``isDone()`方法，以查看服務是否已提供回應物件。當回應準備就緒時，您可以透過呼叫 `Future``get()`方法取得回應物件。您可以使用此機制定期輪詢非同步操作的結果，同時您的應用程式會繼續處理其他項目。

以下是呼叫 Lambda 函數的非同步操作範例，接收可以容納 [InvokeResult](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/lambda/model/InvokeResult.html) 物件`Future`的 。只有在 `isDone()`為 之後，才會擷取`InvokeResult`物件`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);
    }
}
```

## 非同步回呼
<a name="basics-async-callback"></a>

除了使用 Java `Future` 物件來監控非同步請求的狀態之外， 軟體開發套件還可讓您實作使用[AsyncHandler](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/handlers/AsyncHandler.html) 界面的類別。 `AsyncHandler`提供兩種呼叫方法，取決於請求的完成方式： `onSuccess`和 `onError`。

回呼界面方法的主要優點是讓您無需輪詢`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(".");
        }
    }
}
```

## 最佳實務
<a name="basics-async-tips"></a>

### 回呼執行
<a name="callback-execution"></a>

您的 實作`AsyncHandler`會在非同步用戶端擁有的執行緒集區中執行。快速執行的簡短程式碼最適合您的`AsyncHandler`實作。處理常式方法內的長時間執行或封鎖程式碼可能會導致非同步用戶端使用的執行緒集區發生爭用，並可防止用戶端執行請求。如果您有需要從回呼開始的長期執行任務，請讓回呼在新的執行緒或由應用程式管理的執行緒集區中執行其任務。

### 執行緒集區組態
<a name="thread-pool-configuration"></a>

中的非同步用戶端 適用於 Java 的 AWS SDK 提供預設執行緒集區，應適用於大多數應用程式。您可以實作自訂 [ExecutorService](https://docs.oracle.com/javase/8/docs/api/index.html?java/util/concurrent/ExecutorService.html)，並將其傳遞給 適用於 Java 的 AWS SDK 非同步用戶端，以進一步控制執行緒集區的管理方式。

例如，您可以提供使用自訂 [ThreadFactory](https://docs.oracle.com/javase/8/docs/api/index.html?java/util/concurrent/ThreadFactory.html) 來控制集區中執行緒命名方式的`ExecutorService`實作，或記錄有關執行緒用量的其他資訊。

### 非同步存取
<a name="s3-asynchronous-access"></a>

開發套件中的 [TransferManager](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/s3/transfer/TransferManager.html) 類別提供使用 的非同步支援 Amazon S3。 `TransferManager`管理非同步上傳和下載、提供有關傳輸的詳細進度報告，以及支援對不同事件的回呼。