如何以线程安全的方式实施AWS S3客户端?

sha*_*ran 2 java multithreading amazon-s3 thread-safety aws-sdk

您好,我有一个由多个线程同时执行的方法,用于连接到 s3 存储桶对象并读取元数据。所有这些方法都使用单个 s3 客户端对象。根据 Amazon Java SDK 文档,我发现 s3Clients 是线程安全对象。以下实现方式会导致死锁或性能问题吗?在 s3 客户端使用多线程时,这是正确的实现方式吗?

public class S3Client {
    // static method that returns the s3 client for all the requests
    public static AmazonS3 getS3Client(){
        return AmazonS3ClientBuilder.standard().withRegion(Regions.DEFAULT_REGION).build();
    }
}
Run Code Online (Sandbox Code Playgroud)

还有另一个类(RequestHandler->readObject 方法)将由多个线程并发执行。因此将针对每个请求执行。

public class RequestHandler {
    // Multiple concurrent threads are accessing this method
    public void readObject(){
        AmazonS3 s3Client = S3Client.getS3Client();
        ListObjectsV2Result result = s3Client.listObjectsV2("bucket_name");
    }
}
Run Code Online (Sandbox Code Playgroud)

请指教。提前致谢!!

Mik*_*048 5

我们一一来说:

  1. java AWS S3 sdk 中的构建器通常 不是线程安全的S3Client#getS3Client()所以尽量不要在多线程环境下使用。
  2. AmazonS3Client使用@ThreadSafe进行注释。这是Java AWS sdk中的一个注释,它将类标记为线程安全的。因此,无需像您那样创建某种对象工厂,AmazonS3Client每个应用程序只能有一个单例对象。在上面的示例中,您清楚地为每个RequestHandler#readObject()方法调用创建了新实例。它不仅不安全,还可能导致性能问题,因为您将创建大量AmazonS3Client,这会降低您的 java 应用程序垃圾收集过程。

AmazonS3Client如果您只使用单例模式,即通过 spring 或任何其他 IoC 框架创建为单例对象,或者通过您自己(例如通过双重检查锁定) ,您几乎可以解决所有问题。通过这种方式,您将实现线程安全以及相对良好的性能(与问题中的代码相比)。

希望对您有帮助,祝您有美好的一天!)