samedi 2 janvier 2016

Concurrent random number generation in Java

On a web server, many threads are serving the content to the clients. A/B tests are performed on the web site, so we need a PRNG to choose a variant for each session and test. Obviously when using a single instance of a PRNG, it is accessed concurrently, so proper locking or other mechanisms might be required.

Initially we used java.util.Random(juR), but since it has the flaws mentioned e.g. How good is java.util.Random, we tried to use MersenneTwister instead. However we saw a major drop in performance due to the fact that Mersenne-Twister relies on an internal state, so it access to nextInt() needs to be synchronized. An alternative might be an XOR shift PRNG, but it has the same problem as Mersenne Twister. You can find an explanation e.g. here: http://ift.tt/1n5OjpM

Random uses a compareAndSet operation, which seems to be much faster as it does not require locking, but according to the class Javadoc it is still not thread-safe. Instead it is suggested to use ThreadLocalRandom instead, which would basically result in a pool of PRNG's. Upon a request, a random available thread handles the HTTPS request, so a random PRNG is chosen from a set of available PRNG's. Obviously this is quite fast.

Are produced random numbers from such a pool are as good as the ones from a single PRNG instance?

Another approach would be to use a single PRNG instance to pre-generate a stream of values from it e.g. by using ArrayBlockingQueue.

Which solution would work better in terms of performance?




Aucun commentaire:

Enregistrer un commentaire