嗨,我有一个由多个线程同时执行的方法,用于连接到 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();
}
}
还有另一个类(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");
}
}
请指教。提前致谢!!
最佳答案
让我们一一进行:
- java AWS S3 sdk 中的构建器通常 not thread safe 。所以
多线程环境下尽量不要使用
S3Client#getS3Client()
。 - AmazonS3Client注释为 @ThreadSafe 。这是Java AWS sdk中的一个注释,它将类标记为线程安全的。因此,无需像您那样创建某种对象工厂,每个应用程序只能拥有一个
AmazonS3Client
单例对象。在上面的示例中,您清楚地为每个RequestHandler#readObject()
方法调用创建了新实例。这不仅不安全,还可能导致性能问题,因为您将创建大量AmazonS3Client
,这会降低您的 Java 应用程序垃圾收集过程。
如果您只使用单例模式,即通过 spring、任何其他 IoC 框架或您自己创建 AmazonS3Client
作为单例对象,您几乎可以解决所有问题,例如通过 double check locking 。通过这种方式,您将实现线程安全以及相对良好的性能(与问题中的代码相比)。
希望对您有帮助,祝您有美好的一天!)
关于java - 如何以线程安全的方式实现AWS S3客户端?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70687454/