Subclassing java.util.Random

In our discussion of the XORShift generator, we mentioned that we could subclass java.lang.Random to use a different generator.

There is essentially one method that we need to override: the protected method next(), which other methods will call to ask for a certain number of random bits. Here is a naive version, which we'll actually need to correct slightly in a moment:

(追記) (追記ここまで)
public class XORShiftRandom extends Random {
 private long seed = System.nanoTime();
 public XORShiftRandom() {
 }
 protected int next(int nbits) {
 // N.B. Not thread-safe!
 long x = this.seed;
 x ^= (x << 21);
 x ^= (x >>> 35);
 x ^= (x << 4);
 this.seed = x;
 x &= ((1L << nbits) -1);
 return (int) x;
 }
}

In principle, we don't actually care about nbits: the XORShift algorithm produces numbers where we can take all bits as equally random. However, it turns out that other methods of Random rely on exactly the right number of random bits being supplied, and other bits being zero. (In my opinion, the documentation of the next() method is misleading on this point.) So, the line x &= ((1L << nbits) -1) masks off any unwanted bits.

A few details we've glossed over:

  • The implementation above is not thread-safe, whereas the base java.lang.Random is. If we wanted to fix this, we'd declare seed as an AtomicLong and use an atomic update: see the source code to java.lang.Random for an example, plus this site's tutorial on the Java atomic classes.
  • Our implementation wouldn't serialise its state (current seed), unlike java.lang.Random.
  • We might want to override nextLong(), since we can generate 64 bits at a time. This method would then not be able to generate the value zero, of course, but as it stands, there'll always be one value that nextLong() can't generate, since the generator has a period of 264-1, and there are 264 possible longs.

If you enjoy this Java programming article, please share with friends and colleagues. Follow the author on Twitter for the latest news and rants. Follow @BitterCoffey

Editorial page content written by Neil Coffey. Copyright © Javamex UK 2021. All rights reserved.

AltStyle によって変換されたページ (->オリジナル) /