I think I may have confused you with the code. My example was to
contradict your specific claim that T2 never got the lock. With 2
threads running parallel, timing is important, but it isn't true that
one thread always keeps the lock; for example (going back to the
"while" example) I get pretty balanced results as follows:
T2: 46207
T1: 53794
With the code as below; this is two threads contending over a singel
lock, each incrementing a local counter, with 100k iterations (give-or-
take 1). Individual runs might be less balanced (or more balanced)
depending on what the OS is doing, the number of cores available,
karma, etc - but I would not expect to see 100k vs 0, or 0 vs 100k.
Marc
using System.Threading;
using System;
static class Program
{
static void Main()
{
ThreadPool.QueueUserWorkItem(DoWork, "T1");
ThreadPool.QueueUserWorkItem(DoWork, "T2");
Thread.Sleep(500); // let T1 & T2 get to evt.WaitOne
evt.Set();
Console.ReadKey();
}
static readonly ManualResetEvent evt = new
ManualResetEvent(false);
static readonly object sync = new object();
static int tally = 100000;
static void DoWork(object name)
{
int counter = 0;
evt.WaitOne(); // start both at the same time...
while (true)
{
Monitor.Enter(sync);
counter++;
Monitor.Exit(sync);
if(Interlocked.Decrement(ref tally) <= 0) break;
}
Console.WriteLine("{0}: {1}", name, counter);
}
}
|