[英]How to reinitialize inside synchronized block in Java?
我有一个 s3client,它使用具有 60 天轮换策略的密码。 为此,我们使用了一个 s3client object,但是当密码轮换时,所有线程都开始出现异常。 我想捕获并确保只有 1 个线程重新初始化客户端,而其他线程在同步块内什么都不做。 想不出这样做的方法。
private static AtomicBoolean initializingS3Client = new AtomicBoolean(false);
public static AmazonS3 reinitializeAndProvideS3Client() throws Exception {
synchronized (initializingS3Client) {
if (initializingS3Client.compareAndSet(false, true)) {
s3Client.shutdown();
s3Client = createAmazonS3Client();
initializingS3Client.notifyAll();
} else {
initializingS3Client.wait();
}
}
return s3Client;
}
您没有共享执行实际错误处理/触发重新初始化的代码。 我假设您在任何发生的 IOException 上调用该方法。 为避免例如 temporal.network 问题导致数以千计或数百万次意外的重新初始化,我建议指定两次重新初始化之间的最短时间。 这也有助于使代码更简单:
public YourClass {
...
private static final long MIN_TIME_BETWEEN_TWO_REINITIALIZES = 60 * 1_000; // 1 min
privat static long lastReinitialize = 0;
public static AmazonS3 reinitializeAndProvideS3Client() throws Exception {
synchronized (YourClass.class) {
long now = System.currentTimeInMillis();
if (now - lastReinitialize > MIN_TIME_BETWEEN_TWO_REINITIALIZES ) {
s3Client.shutdown();
s3Client = createAmazonS3Client();
lastReinitialize = now;
}
return s3Client;
}
}
}
我假设 s3Client 字段是易变的并且 s3Client 实现是线程安全的。 如果 s3Client 不应该是易失的并且对它的访问应该已经被另一个 object 同步,那么将同步语句中的 YourClass.class 替换为该 object。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.