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
,Java8CompatRandom
,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 aSimpleRandomSeeder
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<? extends 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 whoseSimpleRandomSeeder
uses aSimpleRandomSeeder.DefaultThreadFactory
.SplittableRandomAdapter(SeedGenerator seedGenerator, SimpleRandomSeeder 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 java8.util.SplittableRandom
getSplittableRandom()
Returns theSplittableRandom
that is to be used to generate random numbers for the current thread.int
hashCode()
double
nextGaussian()
Delegates toSplittableRandom.nextDouble()
viaBaseRandom.internalNextGaussian(DoubleSupplier)
.void
setRandomSeeder(SimpleRandomSeeder randomSeeder)
Registers this PRNG with theSimpleRandomSeeder
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, creditEntropyForNewSeed, doubles, doubles, doubles, doubles, dump, entropyOfInt, entropyOfLong, fallbackSetSeedIfInitialized, gaussians, gaussians, getRandomSeeder, initTransientFields, internalNextGaussian, ints, ints, ints, ints, longs, longs, longs, longs, needsReseedingEarly, nextDouble, nextElement, nextElement, nextEnum, nextLong, setSeed, setSeed, supportsMultipleSeedLengths, withProbability
-
-
-
-
Field Detail
-
threadLocal
protected transient ThreadLocal<? extends BaseRandom> threadLocal
A thread-local delegate.
-
-
Constructor Detail
-
SplittableRandomAdapter
public SplittableRandomAdapter(SeedGenerator seedGenerator, @Nullable SimpleRandomSeeder randomSeeder) throws SeedException
Creates an instance.- Parameters:
seedGenerator
- the seed generator that will generate an initial seed for each threadrandomSeeder
- theSimpleRandomSeeder
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 whoseSimpleRandomSeeder
uses aSimpleRandomSeeder.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
-
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 SimpleRandomSeeder randomSeeder)
Description copied from class:BaseRandom
Registers this PRNG with theSimpleRandomSeeder
for the correspondingSeedGenerator
, to schedule reseeding when we run out of entropy. Unregisters this PRNG with the previousSimpleRandomSeeder
if it had a different one.- Overrides:
setRandomSeeder
in classBaseRandom
- Parameters:
randomSeeder
- aSeedGenerator
whoseSimpleRandomSeeder
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 java8.util.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(DoubleSupplier)
.- Specified by:
nextGaussian
in interfaceJava8CompatRandom
- 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.
-
-