This is as much a “before you forget about it” post as anything else.
Both Java and .NET have Random classes, which allow you to get random numbers within a certain range etc. Unless you specify otherwise, both are seeded with the current time. Neither class claims to be thread-safe. This presents a problem – typically you effectively just want one source of random numbers, but you want to be able to access it from multiple threads. You certainly don’t want to create a new instance of the Random class every time you want a random number – due to the granularity of the system clock, that commonly gives repeated sequences of random numbers (i.e. multiple instances are created with the same seed, so each instance gives the same sequence).
I suggest that very few people really need to specify seeds – which means they don’t really need instance methods in the first place. A class with static methods (matching the interface of Random) would be perfectly adequate. This could be implemented using a single Random instance and locking to get thread safety, but a slightly more elegant (or at least more interesting) way would be to use thread-local static variables. In other words, each thread gets its own instance of Random. Now, that introduces the problem of which seed to use for each of these instances. That’s pretty easily solved though – either you take some combination of the thread ID and the current time, or you create a new instance of Random the first time any thread accesses the class, and use that Random as the source of seeds for future Randoms. The only time locking is needed is to access that Random, which occurs once per thread.
This does, of course, break my “keep it as simple as possible” rule – the simplest solution would certainly be to lock each time. In this case though, as this will end up as a library class which may well be used by many threads simultaneously in situations where a lot of random numbers are being generated, I think it’s worth the extra effort. I’ll probably write this up as an article when I’ve written the tests and implementation…