I want to generate some random numbers for many Servlet requests. The problem is if i use a new Random object in each servlet, the overall probability will be incorrect.
E.g. with around 10000+ reqeusts, i expect all random value should be evenly distributed within the range.
So why not use a global
Random
instance?Or you can use
ThreadLocalRandom
which is faster. And it is kind of global because you cannot really create an instance of it. You can get an instance by callingThreadLocalRandom.current()
. In Java 7, it returns a per-thread instance. In Java 8, it is further optimized, it'll always return the same singleton.It is a little bit complicated to get really random sequence using Random. Random is LCG-based with 2^48 period and you need to be very careful with seed. There is a way to generate single sequence using DataStore to keep your current value, but performance will be not very good because you will need to update value every time you generate new random number. It means that you will be able too reach 10-20 request/sec without memcahce and probably around 100 req/sec with memcache. Sharding will not be very helpful because you need to keep atomic seed value.
Algorithm will looks like:
On every next request (whole op should be in a single transcation):
4.1. Read seed from DataStore
4.2. Create new Random with your seed.
4.3. Generate new int.
4.4. Set seed = random <<< 16
4.5. Save seed to DataStore