繁体   English   中英

如何在 Java 中的同步块内重新初始化?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM