

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

# Pemrograman secara asinkron menggunakan AWS SDK for Java 2.x
<a name="asynchronous"></a>

 AWS SDK for Java 2.x Fitur klien asinkron dengan I/O dukungan non-pemblokiran yang menerapkan konkurensi tinggi di beberapa utas. Namun, total non-pemblokiran tidak I/O dijamin. Klien asinkron dapat melakukan pemblokiran panggilan dalam beberapa kasus seperti pengambilan kredensi, penandatanganan permintaan menggunakan [AWS Sigv4 (SigV4)](https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html), atau penemuan titik akhir. 

Metode sinkron memblokir eksekusi thread Anda hingga klien menerima respons dari layanan. Metode asinkron segera kembali, memberikan kontrol kembali ke utas panggilan tanpa menunggu respons.

Karena metode asinkron kembali sebelum respons tersedia, Anda memerlukan cara untuk mendapatkan respons saat sudah siap. Metode untuk klien asinkron di 2.x dari *CompletableFuture objek AWS SDK untuk Java * kembali yang memungkinkan Anda mengakses respons saat sudah siap.

## Gunakan klien asinkron APIs
<a name="basics-async-non-streaming"></a>

*Tanda tangan metode klien asinkron sama dengan rekan sinkron mereka, tetapi metode asinkron mengembalikan [CompletableFuture](https://docs.oracle.com/javase/8/docs/api/index.html?java/util/concurrent/CompletableFuture.html)objek yang berisi hasil operasi asinkron di masa depan.* Jika kesalahan dilemparkan saat metode asinkron SDK dijalankan, kesalahan dilemparkan sebagai. `CompletionException` 

Salah satu pendekatan yang dapat Anda gunakan untuk mendapatkan hasilnya adalah dengan menghubungkan `whenComplete()` metode ke yang `CompletableFuture` dikembalikan oleh pemanggilan metode SDK. `whenComplete()`Metode menerima hasil atau objek Throwable dari tipe `CompletionException` tergantung pada bagaimana panggilan asinkron selesai. Anda memberikan tindakan `whenComplete()` untuk memproses atau memeriksa hasil sebelum dikembalikan ke kode panggilan.

Jika Anda ingin mengembalikan sesuatu selain objek yang dikembalikan oleh metode SDK, gunakan `handle()` metode sebagai gantinya. `handle()`Metode ini mengambil parameter yang sama seperti`whenComplete()`, tetapi Anda dapat memproses hasilnya dan mengembalikan objek.

Untuk menunggu rantai asinkron selesai dan mengambil hasil penyelesaian, Anda dapat memanggil metode. `join()` Jika `Throwable` objek tidak ditangani dalam rantai, `join()` metode melempar tanda centang `CompletionException` yang membungkus pengecualian asli. Anda mengakses pengecualian asli dengan`CompletionException#getCause()`. Anda juga dapat memanggil `CompletableFuture#get()` metode untuk mendapatkan hasil penyelesaian. `get()`Metode ini, bagaimanapun, dapat membuang pengecualian yang diperiksa.

Contoh berikut menunjukkan dua variasi bagaimana Anda dapat bekerja dengan `listTables()` metode klien asinkron DynamoDB. Tindakan diteruskan untuk `whenComplete()` hanya mencatat respons yang berhasil, sedangkan `handle()` versi mengekstrak daftar nama tabel dan mengembalikan daftar. Dalam kedua kasus jika kesalahan dihasilkan dalam rantai asinkron, kesalahan dilemparkan kembali sehingga kode klien memiliki kesempatan untuk menanganinya.

 **Impor** 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbAsyncClient;
import software.amazon.awssdk.services.dynamodb.model.ListTablesRequest;
import software.amazon.awssdk.services.dynamodb.model.ListTablesResponse;

import java.util.List;
import java.util.concurrent.CompletableFuture;
```

 **Kode** 

------
#### [ whenComplete() variation ]

```
public class DynamoDbAsyncListTables {

    public static void main(String[] args) {
        Region region = Region.US_EAST_1;
        DynamoDbAsyncClient dynamoDbAsyncClient = DynamoDbAsyncClient.builder().region(region).build();
        try {
            ListTablesResponse listTablesResponse = listTablesWhenComplete(dynamoDbAsyncClient).join();  // The join() method may throw a CompletionException.
            if (listTablesResponse.hasTableNames()){
                System.out.println("Table exist in this region: " + region.id());
            }
        } catch (RuntimeException e) {
            // Handle as needed. Here we simply print out the class names.
            System.out.println(e.getClass()); // Prints 'class java.util.concurrent.CompletionException'.
            System.out.println(e.getCause().getClass()); // Prints 'class software.amazon.awssdk.services.dynamodb.model.DynamoDbException'.
        }
    }

    public static CompletableFuture<ListTablesResponse> listTablesWhenComplete(DynamoDbAsyncClient client) {
        return client.listTables(ListTablesRequest.builder().build())
            .whenComplete((listTablesResponse, throwable) -> {
                if (listTablesResponse != null) {  // Consume the response.
                    System.out.println("The SDK's listTables method completed successfully.");
                } else {
                    RuntimeException cause = (RuntimeException) throwable.getCause(); // If an error was thrown during the SDK's listTables method it is wrapped in a CompletionException.
                                                                                      // The SDK throws only RuntimeExceptions, so this is a safe cast.
                    System.out.println(cause.getMessage());  // Log error here, but rethrow so the calling code can handle as needed.
                    throw cause;
                }
            });
    }
```

------
#### [ handle() variation ]

```
public class DynamoDbAsyncListTables {

    public static void main(String[] args) {
        Region region = Region.US_EAST_1;
        DynamoDbAsyncClient dynamoDbAsyncClient = DynamoDbAsyncClient.builder().region(region).build();
        try {
            List<String> tableNames = listTablesHandle(dynamoDbAsyncClient).join(); // The join() method may throw a CompletionException.
            tableNames.forEach(System.out::println);
        } catch (RuntimeException e) {
            // Handle as needed. Here we simply print out the class names.
            System.out.println(e.getClass()); // Prints 'class java.util.concurrent.CompletionException'.
            System.out.println(e.getCause().getClass()); // Prints 'class software.amazon.awssdk.services.dynamodb.model.DynamoDbException'.
        }
    }

    public static CompletableFuture<List<String>> listTablesHandle(DynamoDbAsyncClient client) {
        return client.listTables(ListTablesRequest.builder().build())
            .handle((listTablesResponse, throwable) -> {
                if (listTablesResponse != null) {
                    return listTablesResponse.tableNames(); // Return the list of table names.
                } else {
                    RuntimeException cause = (RuntimeException) throwable.getCause(); // If an error was thrown during the SDK's listTables method it is wrapped in a CompletionException.
                                                                                      // The SDK throws only RuntimeExceptions, so this is a safe cast.
                    System.out.println(cause.getMessage());  // Log error here, but rethrow so the calling code can handle as needed.
                    throw cause;
                }
            });
    }
}
```

------

## Menangani streaming dalam metode asinkron
<a name="basics-async-streaming"></a>

Untuk metode asinkron dengan konten streaming, Anda harus menyediakan [AsyncRequestBody](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/async/AsyncRequestBody.html)untuk menyediakan konten secara bertahap, atau [AsyncResponseTransformer](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/async/AsyncResponseTransformer.html)untuk menerima dan memproses respons.

Contoh berikut mengunggah file ke Amazon S3 asinkron dengan menggunakan bentuk operasi asinkron. `PutObject`

 **Impor** 

```
import software.amazon.awssdk.core.async.AsyncRequestBody;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3AsyncClient;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
import software.amazon.awssdk.services.s3.model.PutObjectResponse;
import java.nio.file.Paths;
import java.util.concurrent.CompletableFuture;
```

 **Kode** 

```
/**
 * To run this AWS code example, ensure that you have setup your development environment, including your AWS credentials.
 *
 * For information, see this documentation topic:
 *
 * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
 */

public class S3AsyncOps {

     public static void main(String[] args) {

         final String USAGE = "\n" +
                 "Usage:\n" +
                 "    S3AsyncOps <bucketName> <key> <path>\n\n" +
                 "Where:\n" +
                 "    bucketName - the name of the Amazon S3 bucket (for example, bucket1). \n\n" +
                 "    key - the name of the object (for example, book.pdf). \n" +
                 "    path - the local path to the file (for example, C:/AWS/book.pdf). \n" ;

        if (args.length != 3) {
            System.out.println(USAGE);
             System.exit(1);
        }

        String bucketName = args[0];
        String key = args[1];
        String path = args[2];

        Region region = Region.US_WEST_2;
        S3AsyncClient client = S3AsyncClient.builder()
                .region(region)
                .build();

        PutObjectRequest objectRequest = PutObjectRequest.builder()
                .bucket(bucketName)
                .key(key)
                .build();

        // Put the object into the bucket
        CompletableFuture<PutObjectResponse> future = client.putObject(objectRequest,
                AsyncRequestBody.fromFile(Paths.get(path))
        );
        future.whenComplete((resp, err) -> {
            try {
                if (resp != null) {
                    System.out.println("Object uploaded. Details: " + resp);
                } else {
                    // Handle error
                    err.printStackTrace();
                }
            } finally {
                // Only close the client when you are completely done with it
                client.close();
            }
        });

        future.join();
    }
}
```

Contoh berikut mendapatkan file dari Amazon S3 dengan menggunakan bentuk asinkron operasi. `GetObject`

 **Impor** 

```
import software.amazon.awssdk.core.async.AsyncResponseTransformer;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3AsyncClient;
import software.amazon.awssdk.services.s3.model.GetObjectRequest;
import software.amazon.awssdk.services.s3.model.GetObjectResponse;
import java.nio.file.Paths;
import java.util.concurrent.CompletableFuture;
```

 **Kode** 

```
/**
 * To run this AWS code example, ensure that you have setup your development environment, including your AWS credentials.
 *
 * For information, see this documentation topic:
 *
 * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
 */

public class S3AsyncStreamOps {

    public static void main(String[] args) {

        final String USAGE = "\n" +
                "Usage:\n" +
                "    S3AsyncStreamOps <bucketName> <objectKey> <path>\n\n" +
                "Where:\n" +
                "    bucketName - the name of the Amazon S3 bucket (for example, bucket1). \n\n" +
                "    objectKey - the name of the object (for example, book.pdf). \n" +
                "    path - the local path to the file (for example, C:/AWS/book.pdf). \n" ;

        if (args.length != 3) {
            System.out.println(USAGE);
            System.exit(1);
         }

        String bucketName = args[0];
        String objectKey = args[1];
        String path = args[2];

        Region region = Region.US_WEST_2;
        S3AsyncClient client = S3AsyncClient.builder()
                .region(region)
                .build();

        GetObjectRequest objectRequest = GetObjectRequest.builder()
                .bucket(bucketName)
                .key(objectKey)
                .build();

        CompletableFuture<GetObjectResponse> futureGet = client.getObject(objectRequest,
                AsyncResponseTransformer.toFile(Paths.get(path)));

        futureGet.whenComplete((resp, err) -> {
            try {
                if (resp != null) {
                    System.out.println("Object downloaded. Details: "+resp);
                } else {
                    err.printStackTrace();
                }
            } finally {
               // Only close the client when you are completely done with it
                client.close();
            }
        });
        futureGet.join();
    }
}
```

## Konfigurasikan opsi asinkron lanjutan
<a name="advanced-operations"></a>

 AWS SDK untuk Java 2.x menggunakan [Netty](https://netty.io), kerangka kerja aplikasi jaringan berbasis peristiwa asinkron, untuk menangani thread. I/O AWS SDK untuk Java 2.x membuat Netty `ExecutorService` di belakang, untuk menyelesaikan futures yang dikembalikan dari permintaan klien HTTP hingga ke klien Netty. Abstraksi ini mengurangi risiko aplikasi merusak proses asinkron jika pengembang memilih untuk menghentikan atau menidurkan utas. Secara default, setiap klien asinkron membuat threadpool berdasarkan jumlah prosesor dan mengelola tugas dalam antrian di dalam file. `ExecutorService`

Anda dapat menentukan implementasi JDK tertentu `ExecutorService` ketika Anda membangun klien asinkron Anda. Cuplikan berikut membuat `ExecutorService` dengan jumlah thread tetap.

 **Kode** 

```
S3AsyncClient clientThread = S3AsyncClient.builder()
  .asyncConfiguration(
    b -> b.advancedOption(SdkAdvancedAsyncClientOption
      .FUTURE_COMPLETION_EXECUTOR,
      Executors.newFixedThreadPool(10)
    )
  )
  .build();
```

Untuk mengoptimalkan kinerja, Anda dapat mengelola pelaksana kumpulan utas Anda sendiri, dan menyertakannya saat mengonfigurasi klien Anda.

```
ThreadPoolExecutor executor = new ThreadPoolExecutor(50, 50,
    10, TimeUnit.SECONDS,
    new LinkedBlockingQueue<>(<custom_value>),
    new ThreadFactoryBuilder()
      .threadNamePrefix("sdk-async-response").build());

// Allow idle core threads to time out
executor.allowCoreThreadTimeOut(true);

S3AsyncClient clientThread = S3AsyncClient.builder()
  .asyncConfiguration(
    b -> b.advancedOption(SdkAdvancedAsyncClientOption
      .FUTURE_COMPLETION_EXECUTOR,
      executor
    )
  )
  .build();
```