эффективный способ generateSecureRandom () - PullRequest
1 голос
/ 04 февраля 2020

Метод generateSecureRandom() очень часто вызывается разными потоками, и я использую этот токен также для генерации идентификатора базы данных.

Стоит ли размещать поля random и encoder на уровне класса, чтобы сделать его более эффективным (локально для потока?)?

Если поставить random или encoder на уровне класса, будет ли заблокирован доступ к SecureRandom для других потоков, пока один поток его использует? Я не хочу создавать пул экземпляров SecureRandom, но использую Thread-Local.

public final RandomGenerator{

  public static String generateSecureRandom() {

      // field will be created on each method call
      final SecureRandom random = new SecureRandom();

      // field will be created on each method call
      final Base64.Encoder encoder = Base64.getUrlEncoder().withoutPadding();


      byte[] buffer = new byte[20];
      random.nextBytes(buffer);
      return encoder.encodeToString(buffer);
   }
}

Должен ли я размещать поля random и encoder на уровне метода или на уровне класса?

1 Ответ

3 голосов
/ 04 февраля 2020

Я думаю, использование ThreadLocal и помещение random и encoder на уровень класса лучше, чем использование без TreadLocal.

Кроме того, ставить random и encoder на уровне метода не рекомендуется, поскольку создание new SecureRandom для каждого вызова метода довольно дорого.

public final class SecureRandomString {

    private SecureRandomString() {
    }

    // don't use SecureRandom without ThreadLocal, 
    // because it will block other threads while one thread is using it
//  private static final SecureRandom random = new SecureRandom();

    // use thread local for high throughput
    private static final ThreadLocal<SecureRandom> random = new ThreadLocal<>();

    // the encoder does not need a ThreadLocal 
    // because it is thread safe and no lock is required by accessing it
    private static final Base64.Encoder encoder = Base64.getUrlEncoder().withoutPadding();

    public static String generate() {
        byte[] buffer = new byte[20];
        random.get().nextBytes(buffer);
        return encoder.encodeToString(buffer);
    }
}
...