Work on this small test application to learn threading/locking. I have the following code, I would think that the line should only write to console once. However it doesn’t seem to be working as expected. Any thoughts on why? What I’m trying to do is add this Lot object to a List, then if any other threads try and hit that list, it would block. Am i completely misusing lock here?
class Program
{
static void Main(string[] args)
{
int threadCount = 10;
//spin up x number of test threads
Thread[] threads = new Thread[threadCount];
Work w = new Work();
for (int i = 0; i < threadCount; i++)
{
threads[i] = new Thread(new ThreadStart(w.DoWork));
}
for (int i = 0; i < threadCount; i++)
{
threads[i].Start();
}
// don't let the console close
Console.ReadLine();
}
}
public class Work
{
List<Lot> lots = new List<Lot>();
private static readonly object thisLock = new object();
public void DoWork()
{
Lot lot = new Lot() { LotID = 1, LotNumber = "100" };
LockLot(lot);
}
private void LockLot(Lot lot)
{
// i would think that "Lot has been added" should only print once?
lock (thisLock)
{
if(!lots.Contains(lot))
{
lots.Add(lot);
Console.WriteLine("Lot has been added");
}
}
}
}
The
lockstatement ensures that two pieces of code will not execute simultaneously.If two threads enter a
lockblock at once, the seconbd thread will wait until the first one finishes, then continue and execute the block.In your code,
lots.Contains(lot)is alwaysfalsebecause theDoWorkmethod creates a differentLotobject in each thread. Therefore, eah thread adds anotherLotobject after acquiring the lock.You probably want to override
EqualsandGetHashCodein yourLotclass and make it compare by value, so thatlots.Contains(lot)will returntruefor differentLotobjects with the same values.