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



Hi我有一个方法,由多个线程同时执行,以连接到s3 bucket对象并读取元数据。所有这些方法都使用一个s3客户端对象。根据AmazonJavaSDK文档,我发现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();
}
}

还有另一个类(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");
}
}

请提供建议。提前感谢!!

让我们逐一进行:

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

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

希望它有所帮助,祝你今天愉快!(

最新更新