Is Random class truly thread safe?
-
Thursday, February 17, 2011 3:21 AM
MSDN says "Any public static (Shared in Visual Basic) members of this type are thread safe."
I am confronting a problem that makes me wonder if this is true or I am doing something wrong. I made a project in VS to test this. It seems after generating a few hundred thousands to a few million random numbers, it generates nothing but zero. Appended is the code of the test project. Could anyone help point out what I am doing wrong here?
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; namespace SilverlightApplication1 { public partial class MainPage : UserControl { public MainPage() { InitializeComponent(); System.ComponentModel.BackgroundWorker bw1 = new System.ComponentModel.BackgroundWorker(); bw1.DoWork += new System.ComponentModel.DoWorkEventHandler(DoWork); bw1.RunWorkerAsync(lblThread1); System.ComponentModel.BackgroundWorker bw2 = new System.ComponentModel.BackgroundWorker(); bw2.DoWork += new System.ComponentModel.DoWorkEventHandler(DoWork); bw2.RunWorkerAsync(lblThread2); } public static Random rdm = new Random(); void DoWork(object sender, System.ComponentModel.DoWorkEventArgs e) { Label lbl = e.Argument as Label; int iCount = 0; while (true) { double d = rdm.NextDouble(); if (++iCount % 7000 == 0) { lbl.Dispatcher.BeginInvoke(() => { lbl.Content = d.ToString(); } ); System.Threading.Thread.Sleep(10); } } } } }
<UserControl x:Class="SilverlightApplication1.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="400" xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"> <Grid x:Name="LayoutRoot" Background="White"> <sdk:Label Name="lblThread1" Height="28" HorizontalAlignment="Left" Margin="170,108,0,0" VerticalAlignment="Top" Width="120" /> <sdk:Label Name="lblThread2" Height="28" HorizontalAlignment="Left" Margin="170,156,0,0" VerticalAlignment="Top" Width="120" /> </Grid> </UserControl>
hz
Answers
-
Thursday, February 17, 2011 3:45 AM
You quoted only part of the MSDN...the full quote is:
"Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe."
Only the static methods of the Random class are thread safe...and guess what? There are no static methods in the Random class :) Just because you create a static Random object doesn't mean that you're not still calling instance members on it...which aren't thread-safe.
ShaneB
- Marked As Answer by hipswich Thursday, February 17, 2011 4:06 AM
-
Thursday, February 17, 2011 4:20 AM
Yep ...and your confusion is understandable.
Anyway, you can use a lock statement and create an accessor to your Random object to allow multi-threaded access to it. Which is a lot better than creating tons of Random objects.
ShaneB
- Marked As Answer by hipswich Thursday, February 17, 2011 4:23 AM
All Replies
-
Thursday, February 17, 2011 3:45 AM
You quoted only part of the MSDN...the full quote is:
"Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe."
Only the static methods of the Random class are thread safe...and guess what? There are no static methods in the Random class :) Just because you create a static Random object doesn't mean that you're not still calling instance members on it...which aren't thread-safe.
ShaneB
- Marked As Answer by hipswich Thursday, February 17, 2011 4:06 AM
-
Thursday, February 17, 2011 4:16 AM
Thanks a lot for the elucidation, Shane.
This means that I completely misunderstood the sentence. I thought "Any public static (Shared in Visual Basic) members of this type" meant any public static (Shared in Visual Basic) members of this type of any class such as MainPage in my test sample and this why I created a public static Random type member...
So, is it fair to say that Random is essentially not thread safe considering it has no static members?
hz- Edited by hipswich Thursday, February 17, 2011 4:23 AM
-
Thursday, February 17, 2011 4:20 AM
Yep ...and your confusion is understandable.
Anyway, you can use a lock statement and create an accessor to your Random object to allow multi-threaded access to it. Which is a lot better than creating tons of Random objects.
ShaneB
- Marked As Answer by hipswich Thursday, February 17, 2011 4:23 AM
-
Saturday, July 16, 2011 8:09 AM
Hi, I just had this problem today, and reached the same conclusion (after writing a similar PoC)
Here are two blog posts with more details, comments and code samples on this topic:
The worse part of this behaviour is that it just stops working (i.e. once the problem occurs the return value from the 'random.Next....' methods is 0)
OWASP