This question regards the implementation of ThreadLocalRandom in OpenJDK version 1.8.0.
ThreadLocalRandom provides a per-thread random number generator without the synchronization overhead imposed by Random. The most obvious implementation (IMO) would be something like this, which appears to preserve backward compatibility without much complexity:
public class ThreadLocalRandom extends Random {
private static final ThreadLocal<ThreadLocalRandom> tl =
ThreadLocal.withInitial(ThreadLocalRandom::new);
public static ThreadLocalRandom current() {
return tl.get();
}
// Random methods moved here without synchronization
// stream methods here
}
public class Random {
private ThreadLocalRandom delegate = new ThreadLocalRandom();
// methods synchronize and delegate for backward compatibility
}
However, the actual implementation is totally different and quite bizarre:
ThreadLocalRandomduplicates some of the methods inRandomverbatim and others with minor modifications; surely much of this code could have been reused.Threadstores the seed and a probe variable used to initialize the `ThreadLocalRandom, violating encapsulation;ThreadLocalRandomusesUnsafeto access the variables inThread, which I suppose is because the two classes are in different packages yet the state variables must be private inThread-Unsafeis only necessary because of the encapsulation violation;ThreadLocalRandomstores its nextnextGaussianin a staticThreadLocalinstead of in an instance variable asRandomdoes.
Overall my cursory inspection seems to reveal an ugly copy of Random with no advantages over the simple implementation above. But the authors of the standard library are smart so there must be some reason for this weird approach. Does anyone have any insight into why ThreadLocalRandom was implemented this way?