Say I have two classes like this:
class A{
private static Random random = new Random();
public A(){
// Do something.
}
public Integer methodGetsCalledQuiteOften(){
return random.nextInt();
}
}
class B{
private Random random;
public A(){
random = new Random();
// Do something.
}
public Integer methodGetsCalledQuiteOften(){
return random.nextInt();
}
}
In a scenario where both of them get instantiated multiple times and both of these classes' instances' method methodGetsCalledQuiteOften
gets called a lot, is there any real advantage/disadvantage (time, memory) in using a static variable that holds Random()
in class A as opposed to creating a new Random()
object in every single instance, like in class B?
The application is multithreaded and higher level of randomness is so I think I am going with static SecureRandom
. If that will be a real speed factor after profiling I might choose something else.
access to static resources is not thread safe. You might get weird/unpredictable results in a threaded environment.
Well, since
Random
class takes necessary steps to ensure thread-safety, I see no problem with making it static.And since its state includes single
AtomicLong
object (8 bytes), it's no big waste of memory (unless you're planning on creating huge amount ofB
instances).So, I'd say, there's little difference either way.
Real advantage/disadvantages depend on real code. In other words, it depends on how often a
B
is created compared to how often the method is called, etc. You should profile your application and see whether it makes a reasonable difference.Will A be more performant than B? Certainly. But whether you'll ever notice depends on your usage. Will A use less memory than B? Certainly, but whether you care or not depends on how many instances of A/B you're keeping around.
Really the only other consideration is determinism. Since you don't specify the seed for the Random instance, I take it you don't care whether you can reproduce the sequence of numbers from the Random. But it's worth noting...if you have a shared Random, it will be much harder to guarantee a certain deterministic sequence of numbers for some instance of A than it is with one per instance as in B.
Although instantiating Class A is substantialy (10x) faster than Class B, this only matters if you do this like 100.000 times a second.
About thread safety, it's my understanding that .nextInt() is based on .next() which should be thread safe. So multi threading should not give any problems here.
But more importantly, the behaviour of both classes might be different. Instances of Class A will give each a somewhat random sequence of numbers, but instances of Class B might each give the same sequence of 'random' numbers (this behavior can be different on different platforms!). The Javadoc spec states:
Thus if randomness is important you might want to consider giving an unique seed to the Random constructor or better implement Random with the slower java.security.SecureRandom.