Class SplittableRandomAdapter
- java.lang.Object
-
- java.util.Random
-
- io.github.pr0methean.betterrandom.prng.BaseRandom
-
- io.github.pr0methean.betterrandom.prng.adapter.BaseSplittableRandomAdapter
-
- io.github.pr0methean.betterrandom.prng.adapter.SplittableRandomAdapter
-
- All Implemented Interfaces:
ByteArrayReseedableRandom
,EntropyCountingRandom
,RepeatableRandom
,Dumpable
,Serializable
- Direct Known Subclasses:
EntropyBlockingSplittableRandomAdapter
public class SplittableRandomAdapter extends BaseSplittableRandomAdapter
Thread-safe PRNG that wraps aThreadLocal
<SplittableRandom
>. Registers each thread's instance with aRandomSeeder
to replace itsSplittableRandom
with a reseeded one as frequently as possible, but not more frequently than it is being used.In OpenJDK 8 and Android API 24 and later,
ThreadLocalRandom
uses the same PRNG algorithm asSplittableRandom
, and is faster because of internal coupling withThread
. As well, the instance returned byThreadLocalRandom.current()
can be safely passed to any thread that has ever calledcurrent()
, and streams created by a ThreadLocalRandom are safely parallel. Thus, this class should only be used when reseeding or the ability to specify a seed is required, or for compatibility with JDK 7 or an older Android version.- Author:
- Chris Hennick
- See Also:
- Serialized Form
-
-
Field Summary
Fields Modifier and Type Field Description protected ThreadLocal<BaseRandom>
threadLocal
A thread-local delegate.-
Fields inherited from class io.github.pr0methean.betterrandom.prng.BaseRandom
ENTROPY_OF_DOUBLE, ENTROPY_OF_FLOAT, entropyBits, lock, randomSeeder, seed, superConstructorFinished
-
-
Constructor Summary
Constructors Constructor Description SplittableRandomAdapter(SeedGenerator seedGenerator)
Creates an instance that uses the sameSeedGenerator
for reseeding and for initial seeding, and whoseRandomSeeder
uses aRandomSeeder.DefaultThreadFactory
.SplittableRandomAdapter(SeedGenerator seedGenerator, RandomSeeder randomSeeder)
Creates an instance.
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description protected MoreObjects.ToStringHelper
addSubclassFields(MoreObjects.ToStringHelper original)
Adds the fields that were not inherited from BaseRandom to the givenMoreObjects.ToStringHelper
for dumping.protected BaseRandom
createDelegate()
Creates the delegate for the calling thread.protected void
debitEntropy(long bits)
Record that entropy has been spent, and schedule a reseeding if this PRNG has now spent as much as it's been seeded with.boolean
equals(Object o)
long
getEntropyBits()
Returns an estimate of the current amount of entropy.byte[]
getSeed()
Returns the seed.protected SplittableRandom
getSplittableRandom()
Returns theSplittableRandom
that is to be used to generate random numbers for the current thread.int
hashCode()
protected void
initTransientFields()
Called in constructor and readObject to initialize transient fields.double
nextGaussian()
void
setRandomSeeder(RandomSeeder randomSeeder)
Registers this PRNG with theRandomSeeder
for the correspondingSeedGenerator
, to schedule reseeding when we run out of entropy.protected void
setSeedInternal(byte[] seed)
Sets the seed, and should be overridden to set other state that derives from the seed.String
toString()
boolean
usesParallelStreams()
-
Methods inherited from class io.github.pr0methean.betterrandom.prng.adapter.BaseSplittableRandomAdapter
getNewSeedLength, lockForNextGaussian, next, nextBoolean, nextBytes, nextDouble, nextDouble, nextDoubleNoEntropyDebit, nextFloat, nextInt, nextInt, nextInt, nextLong, nextLong, nextLongNoEntropyDebit, preferSeedWithLong, unlockForNextGaussian, withProbabilityInternal
-
Methods inherited from class io.github.pr0methean.betterrandom.prng.BaseRandom
checkLength, checkValidRange, creditEntropyForNewSeed, doubles, doubles, doubles, doubles, dump, entropyOfInt, entropyOfLong, fallbackSetSeedIfInitialized, gaussians, gaussians, getRandomSeeder, internalNextGaussian, ints, ints, ints, ints, longs, longs, longs, longs, nextDouble, nextElement, nextElement, nextEnum, nextLong, setSeed, setSeed, supportsMultipleSeedLengths, withProbability
-
Methods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
-
Methods inherited from interface io.github.pr0methean.betterrandom.EntropyCountingRandom
needsReseedingEarly
-
-
-
-
Field Detail
-
threadLocal
protected transient ThreadLocal<BaseRandom> threadLocal
A thread-local delegate.
-
-
Constructor Detail
-
SplittableRandomAdapter
public SplittableRandomAdapter(SeedGenerator seedGenerator, @Nullable RandomSeeder randomSeeder) throws SeedException
Creates an instance.- Parameters:
seedGenerator
- the seed generator that will generate an initial seed for each threadrandomSeeder
- theRandomSeeder
that will generate a seed for a newSplittableRandom
instance whenever each thread's instance needs reseeding- Throws:
SeedException
- ifseedGenerator
fails to generate an initial seed
-
SplittableRandomAdapter
public SplittableRandomAdapter(SeedGenerator seedGenerator)
Creates an instance that uses the sameSeedGenerator
for reseeding and for initial seeding, and whoseRandomSeeder
uses aRandomSeeder.DefaultThreadFactory
.- Parameters:
seedGenerator
- the seed generator that will generate an initial seed for each thread- Throws:
SeedException
- ifseedGenerator
fails to generate an initial seed
-
-
Method Detail
-
initTransientFields
protected void initTransientFields()
Description copied from class:BaseRandom
Called in constructor and readObject to initialize transient fields.- Overrides:
initTransientFields
in classBaseRandom
-
createDelegate
protected BaseRandom createDelegate()
Creates the delegate for the calling thread.- Returns:
- the thread-local delegate
-
getEntropyBits
public long getEntropyBits()
Description copied from interface:EntropyCountingRandom
Returns an estimate of the current amount of entropy. Every time the PRNG is reseeded, the entropy count is set to the new seed's length; and every time it is used, it is decreased by the number of random bits in the output rounded up. The amount of entropy can go below zero, giving an indication of how far the entropy has been stretched. This estimate is a lower bound if the seed is perfectly random and is not being reused.- Specified by:
getEntropyBits
in interfaceEntropyCountingRandom
- Overrides:
getEntropyBits
in classBaseRandom
- Returns:
- The current estimated amount of entropy.
-
getSeed
public byte[] getSeed()
Description copied from interface:RepeatableRandom
Returns the seed.- Specified by:
getSeed
in interfaceRepeatableRandom
- Overrides:
getSeed
in classBaseRandom
- Returns:
- The seed data used to initialize this pseudo-random number generator.
-
setRandomSeeder
public void setRandomSeeder(@Nullable RandomSeeder randomSeeder)
Description copied from class:BaseRandom
Registers this PRNG with theRandomSeeder
for the correspondingSeedGenerator
, to schedule reseeding when we run out of entropy. Unregisters this PRNG with the previousRandomSeeder
if it had a different one.- Overrides:
setRandomSeeder
in classBaseRandom
- Parameters:
randomSeeder
- aSeedGenerator
whoseRandomSeeder
will be used to reseed this PRNG, or null to stop using one.
-
usesParallelStreams
public boolean usesParallelStreams()
- Overrides:
usesParallelStreams
in classBaseRandom
- Returns:
- true if this PRNG creates parallel streams; false otherwise.
-
addSubclassFields
protected MoreObjects.ToStringHelper addSubclassFields(MoreObjects.ToStringHelper original)
Description copied from class:BaseRandom
Adds the fields that were not inherited from BaseRandom to the givenMoreObjects.ToStringHelper
for dumping.- Specified by:
addSubclassFields
in classBaseRandom
- Parameters:
original
- aMoreObjects.ToStringHelper
object.- Returns:
original
with the fields not inherited from BaseRandom written to it.
-
getSplittableRandom
protected SplittableRandom getSplittableRandom()
Description copied from class:BaseSplittableRandomAdapter
Returns theSplittableRandom
that is to be used to generate random numbers for the current thread. (SplittableRandom
isn't thread-safe.) Called by all thenext*
methods.- Specified by:
getSplittableRandom
in classBaseSplittableRandomAdapter
- Returns:
- the
SplittableRandom
to use with the current thread.
-
nextGaussian
public double nextGaussian()
Description copied from class:BaseSplittableRandomAdapter
Delegates toSplittableRandom.nextDouble()
viaBaseRandom.internalNextGaussian(java.util.function.DoubleSupplier)
.- Overrides:
nextGaussian
in classBaseSplittableRandomAdapter
-
debitEntropy
protected void debitEntropy(long bits)
Description copied from class:BaseRandom
Record that entropy has been spent, and schedule a reseeding if this PRNG has now spent as much as it's been seeded with.- Overrides:
debitEntropy
in classBaseRandom
- Parameters:
bits
- The number of bits of entropy spent.
-
setSeedInternal
protected void setSeedInternal(byte[] seed)
Description copied from class:BaseRandom
Sets the seed, and should be overridden to set other state that derives from the seed. Called byBaseRandom.setSeed(byte[])
, constructors, andreadObject(ObjectInputStream)
. When called after initialization, theBaseRandom.lock
is always held.- Overrides:
setSeedInternal
in classBaseRandom
- Parameters:
seed
- The new seed.
-
-