Apache Commons logo Apache Commons RNG

The "Apache Commons RNG" project started off from code originally in the "Apache Commons Math" project; there, the code in package org.apache.commons.math3.random had its design prominently based on the JDK's Random class.

Although it is often a good idea to rely on the language's standard library, sometimes it is not.

  • The LCG algorithm used by java.util.Random
    • has a serious defect, and
    • is not as efficient as some of the alternatives that do not suffer from this problem.
  • Although the next method seems to imply that it is designed for inheritance, it is not quite so:
    • setSeed is tied to the assumption that the state of the generator is entirely defined by a single long value.
    • next implies that an implementation must produce a 32-bits value.
    • Random is Serializable and thus imposes it on subclasses even though the issue of persistent storage is application-dependent.

    As a side note, the newer SplittableRandom

    • is final (hence, there is no temptation to mistake it as an interface), and
    • does not inherit from Random (which is a clear hint that the JDK's developers themselves do not consider Random as the best option for new code).
  • Thus, java.util.Random should have been an implementation of a more general interface (without a setSeed method that is bound to be implementation-specific, or a nextGaussian that singles out just one of many types of random deviates).
  • As a concrete class, java.util.Random contains code tied to "implementation details"; it is hard to modify it without changing long-established behavior, even if it would be to fix a bug.
  • Methods are synchronized, incurring an unnecessary performance impact for single-threaded applications, while multi-threaded ones will be subject to contention.

Unless unfazed by the above, it is clear that application developers should avoid java.util.Random, as a generator, and as a base class.

For new applications, it is recommended to switch to any of the better alternatives provided in "Commons RNG".

For legacy applications where the java.util.Random type is part of an API that cannot be changed, developers can wrap any of the generators implemented in this library within an instance of the JDKRandomBridge adapter class.