[잔디일기] 랜덤 값 만들기

처음에 랜덤 값을 만드는 방법으로 Random 클래스와 함께 seed 값으로 시스템의 현재 시간을 사용하였습니다.

private int makeRewardPoint() {
    long seed = System.currentTimeMillis();
    Random random = new Random(seed);
    return random.nextInt(10) + 1;
}

 

하지만 프로젝트를 리팩토링하면서 고민해보게 된 2가지로 인해 알아보다가 ThreadLocalRandom클래스로 변경하게 되었습니다.

  1. 메서드가 동작할 때마다 새로운 Random 클래스를 재생성 해도 괜찮은가?
  2. 동일한 시간에 여러 개의 요청이 동시에 들어온다면?

물론, '잔디일기'의 서비스의 경우 일기를 작성 했을 때 랜덤 값으로 포인트가 적립 되었을 때 작동되는 것이기 때문에 2번의 경우 고려하지 않아도 되는 부분입니다. 하지만 1번의 경우 서버의 성능을 생각했을 때 불필요할 것이라고 생각했고, 찾아본 결과 ThreadLocalRandom 클래스에 대해 알게 되었습니다.

 

Random 클래스와 ThreadLocalRandom 클래스의 큰 차이점은 다음과 같습니다.

- 멀티스레드 환경을 염두에 두고 설계된 ThreadLocalRandom은 각 스레드 마다 독립적인 인스턴스를 제공하여 스레드 안정성을 보장하면서도 성능을 저하시키지 않습니다.
- 반면, Random은 단순성과 사용 편의성이 우선시되는 단일 스레드에서 좋은 성능을 발휘합니다. 가볍기 때문에 빠른 난수 생성 작업에 적합합니다. 또한 레거시 코드를 다루거나 시드 생성에 대한 정확한 제어가 필요한 경우 실용적인 선택이 될 수 있습니다.

ThreadLocalRandom은 기본적으로 스레드 로컬 변수를 사용하여 각 스레드가 독립적인 난수 생성기를 가지도록 설계되었습니다. 따라서 ThreadLocalRandom을 사용할 때는 ThreadLocalRandom.current() 메서드를 호출하여 현재 스레드에 대한 ThreadLocalRandom 인스턴스를 얻어 사용하면 됩니다.

결과

아래 메서드의 결과는 50-100사이의 랜덤한 10단위 값입니다.

import java.util.concurrent.ThreadLocalRandom;

public class DiaryService {
    public int makeRewardPoint() {
        return 50 + (ThreadLocalRandom.current().nextInt(6) * 10);
    }
}

 

스레드 안정성, 성능과 함께 가독성도 향상되었습니다.

참고