nimo23
nimo23

Reputation: 5700

performant way of generateSecureRandom()

The method generateSecureRandom() is called very often by different threads and I use this token also for database ID generation.

Should I put the fields random and encoder on class level to make it more efficient (thread-local?) ?

If put random or encoder on class level, will the access to SecureRandom be locked for other threads while one thread is using it? I do not want to create a pool of SecureRandom instances but use 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);
   }
}

Should I put the fields random and encoder on method level or on class level?

Upvotes: 2

Views: 409

Answers (1)

nimo23
nimo23

Reputation: 5700

I think, using ThreadLocal and putting random and encoder on class level is better than using it without TreadLocal.

Besides, putting random and encoder on method level is not recommended because creating new SecureRandom on each method call is quite expensive..

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

Upvotes: 6

Related Questions