Race Conditions, Synchornized methods and overloading, oh my...
The question was brought up, and I had to find out what the behavior is under this conditions. Here is the test scenario:
class Program
{
Hashtable t = new Hashtable();
ManualResetEvent startAllAtOnce = new ManualResetEvent(true);
static void Main(string[] args)
{
Program p = new Program();
List<Thread> threads = new List<Thread>();
for (int i = 0; i < 50; i++)
{
Thread thread = new Thread(p.DoWork);
threads.Add(thread);
thread.Start();
}
p.startAllAtOnce.Set();
foreach (Thread thread in threads)
{
thread.Join();
}
}
public void DoWork()
{
startAllAtOnce.WaitOne();
if(t.ContainsKey("aabc")==false)
{
Thread.Sleep(100);
t.Add("aabc","cc");
}
}
}
This method simulate a race condition, it is a very simple test case, if it throws an exception, the test is failing.
Right now, trying to run the code above will throw. Let us try something a bit more sophisticated.
[MethodImpl(MethodImplOptions.Synchronized)]
public void DoWork()
{
startAllAtOnce.WaitOne();
if(t.ContainsKey("aabc")==false)
{
Thread.Sleep(100);
t.Add("aabc","cc");
}
}
The method has an attribute that tells the runtime that only one thread can execute this method (per instance, by the way). Now, what happens when you throw virtual methods into the mix? Let us try this:
class Derived : Program
{
public override void DoWork()
{
startAllAtOnce.WaitOne();
if (t.ContainsKey("aabc") == false)
{
Thread.Sleep(100);
t.Add("aabc", "cc");
}
}
}
Let us change the first line of Main to:
Program p = new Derived();
Now it throws. The synchronized option is not inherited. The most interesting part comes when you try to do this for across the hierarcy, where it also doesn't work (because it is using a different instance).
Just a little tibit that is interesting to know... This just went to the list of "Thing you are going to get asked if you tell me that you know .Net multi threading*".
* Asked meaning that you get Visual Stuido and ~10 minutes to figure it out.
Comments
Comment preview