Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What happens if I lock an object while another thread use that variable?

I am not sure how lock works.
What happens if I have a List<T> list and 2 threads ?
What happens if thread1 start running first and enumerate that list

foreach(T t in list)
{
  // code
}

and in the same time, but after thread1 has started, thread2 will lock the list

lock(list)
{ 
  // code
}

I use ThreadPool do to some processing and I need to know how lock really works and if is thread safe

ThreadPool.QueueUserWorkItem(new WaitCallback(method), obj);
like image 253
Sorin Avatar asked Oct 07 '09 10:10

Sorin


Video Answer


3 Answers

lock keyword doesn't "lock" or "freeze" target object (in a sense preventing from changes).

lock ensures that one thread does not enter a critical section of code while another thread is in the critical section. If another thread attempts to enter a locked code, it will wait, block, until the object is released.

So in your case it won't prevent other threads from enumerating the list.

like image 176
Dzmitry Huba Avatar answered Oct 10 '22 16:10

Dzmitry Huba


In the code as written - the enumerator will keep on going. The point about lock is that all your code needs to agree. If you had used:

lock(list)
{
    foreach(T t in list)
    {
        // code
    }
}

Then when your other thread attempts to acquire the lock it will queue behind the first - waiting for the first thread to release the lock (either by exiting the lock (Monitor.Exit), or calling Monitor.Wait).

like image 33
Marc Gravell Avatar answered Oct 10 '22 16:10

Marc Gravell


Lock isn't magic, and it must be used cooperatively. If I want to ensure that changes to some mutable object don't get accidentally stomped on or corrupted by multiple threads then I need to ensure that I only make changes to the object within a lock block.

The only thing that lock ensures is that any other code that is locking on the same object is not running on other threads at the same time, it's just syntactic sugar for acquiring and releasing a mutex.

lock(x) // acquire mutex associated with x, or wait until it becomes available
{
    // do stuff
} // release mutex associated with x

Edit: MSDN has very worthwhile under-the-hood details on lock(), for those who are curious.

like image 29
Wedge Avatar answered Oct 10 '22 18:10

Wedge