Is C#'s Random.Next()
method is thread safe?
相关问题
- Sorting 3 numbers without branching [closed]
- Graphics.DrawImage() - Throws out of memory except
- Why am I getting UnauthorizedAccessException on th
- 求获取指定qq 资料的方法
- How to know full paths to DLL's from .csproj f
Per documentation
http://msdn.microsoft.com/en-us/library/system.random.aspx
The traditional thread local storage approach can be improved upon by using a lock-less algorithm for the seed. The following was shamelessly stolen from Java's algorithm (possibly even improving on it):
Another thread safe way is to use
ThreadLocal<T>
as follows:The
GenerateSeed()
method will need to return a unique value each time it is called to assure that the random number sequences are unique in each thread.Will work for small numbers of threads.
For what its worth, here is a thread-safe, cryptographically strong RNG that inherits
Random
.The implementation includes static entry points for ease of use, they have the same names as the public instance methods but are prefixed with "Get".
A call to the
RNGCryptoServiceProvider.GetBytes
is a relatively expensive operation. This is mitigated through the use of an internal buffer or "Pool" to make less frequent, and more efficient use ofRNGCryptoServiceProvider
. If there are few generations in an application domain then this could be viewed as overhead.No, using the same instance from multiple threads can cause it to break and return all 0's. However, creating a thread-safe version (without needing nasty locks on every call to
Next()
) is simple. Adapted from the idea in this article:The idea is to keep a separate
static Random
variable for each thread. Doing that in the obvious way fails, however, because of another issue withRandom
- if multiple instances are created at nearly the same time (within about 15ms), they will all return the same values! To fix this, we create a globally-staticRandom
instance to generate the seeds used by each thread.The above article, by the way, has code demonstrating both of these issues with
Random
.There's nothing special done in the
Next
method to achieve thread safety. However, it's an instance method. If you don't share instances ofRandom
across different threads, you don't have to worry about state corruption within an instance. Do not use a single instance ofRandom
across different threads without holding an exclusive lock of some sort.Jon Skeet has a couple nice posts on this subject:
StaticRandom
Revisiting randomness
As noted by some commentators, there is another potential problem in using different instances of
Random
that are thread-exclusive, but are seeded identically, and therefore induce the identical sequences of pseudorandom numbers, because they may be created at the same time or within close temporal proximity of each other. One way to alleviate that issue is to use a masterRandom
instance (which is locked by a single thread) to generate some random seeds and initialize newRandom
instances for every other thread to use.