Как выполнить повторную инициализацию внутри синхронизированного блока в Java? - PullRequest
0 голосов
/ 28 мая 2020

У меня есть s3client, который использует пароль с политикой ротации 60 дней. Для этого у нас используется единственный объект s3client, но при смене пароля все потоки начинают выдавать исключения. Я хочу поймать и убедиться, что только один поток повторно инициализирует клиента, а другие ничего не делают внутри синхронизированного блока. Не могу придумать, как это сделать.

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;
}

1 Ответ

1 голос
/ 28 мая 2020

Вы не поделились кодом, который выполняет фактическую обработку ошибок / запускает повторную инициализацию. Я предполагаю, что вы вызываете метод при возникновении исключения IOException. Чтобы избежать этого, например, временные проблемы с сетью приводят к тысячам или миллионам повторных инициализаций без инициализации, я бы предложил указать минимальное время между двумя повторными инициализациями. Это также помогает упростить код:

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 не должен быть изменчивым и доступ к нему уже должен быть синхронизирован другим объектом, замените YourClass.class в операторе synchronized на этот объект.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...