如果我在另一个线程使用该变量时锁定一个对象会发生什么?

时间:2009-10-07 10:49:46

标签: c# multithreading locking

我不确定锁是如何工作的 如果我有List<T> list和2个帖子会发生什么? 如果thread1首先开始运行并枚举该列表

,会发生什么
foreach(T t in list)
{
  // code
}

并且在同一时间,但在thread1启动后,thread2将锁定列表

lock(list)
{ 
  // code
}

我使用ThreadPool做一些处理,我需要知道锁是如何工作的,如果是线程安全的

ThreadPool.QueueUserWorkItem(new WaitCallback(method), obj);

3 个答案:

答案 0 :(得分:5)

lock keyword不会“锁定”或“冻结”目标对象(在某种意义上可以防止更改)。

  

lock确保一个线程不进入代码的关键部分,而另一个线程处于临界区。如果另一个线程试图输入一个锁定的代码,它将等待,阻止,直到该对象被释放。

因此,在您的情况下,它不会阻止其他线程枚举列表。

答案 1 :(得分:5)

在编写的代码中 - 枚举器将继续运行。关于lock的要点是您的代码需要同意的全部。如果你曾经使用过:

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

然后,当你的其他线程尝试获取锁时,它将在第一个线程后面排队 - 等待第一个线程释放锁定(退出lock({{1 }},或致电Monitor.Exit)。

答案 2 :(得分:1)

锁定不是魔法,必须合作使用。如果我想确保对某些可变对象的更改不会被多个线程意外地踩踏或损坏,那么我需要确保我只对锁定块中的对象进行更改。

锁定唯一确保的是锁定在同一对象上的任何其他代码不会同时在其他线程上运行,它只是获取和释放互斥锁的语法糖。

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

编辑:对于那些好奇的人来说,MSDN非常值得under-the-hood details on lock()