锁定如何应对竞争条件?

时间:2009-02-18 20:11:26

标签: .net multithreading synchronization locking race-condition

在以下情况中,线程等待竞争条件需要多长时间?

将文件添加到集合中:

 lock(mylock)
 {
     // add to collection
 }

然后以类似的方式从集合中删除它。

如果某个线程在服务将其从集合中删除时尝试添加到集合中,谁赢了?

或者说这是竞争条件,你无法预测谁获胜?

4 个答案:

答案 0 :(得分:6)

如果删除线程首先尝试锁定,它拥有锁,删除该项(如果存在),释放锁,然后继续。然后添加线程抓住锁并添加项。 最终结果:项目存在于集合中。

如果添加线程首先尝试锁定,则它拥有锁定,添加项目,释放锁定并继续前进。然后删除线程抓取锁并删除(刚刚添加的)项。 最终结果:项目 不存在于集合中。

两个线程都不会等待超过从集合中添加或删除项目所需的时间。

答案 1 :(得分:6)

顾名思义,竞争条件意味着有竞争,任何人都可以获胜!

如此处所示使用lock(obj)将导致线程阻塞(等待),直到所有其他线程在obj上释放锁定。这可能永远不会发生。

lock (obj)
{
    // stuff
}

......等同于......

Monitor.Enter(obj);
try
{
    // stuff
}
finally
{
    Monitor.Exit(obj);
}

如果要强制执行锁定超时,请改用此表单:

if (!Monitor.TryEnter(obj, timeout))
{
    // handle the fact that you couldn't lock
}
else
{
    try
    {
        // stuff
    }
    finally
    {
        Monitor.Exit(obj);
    }
}

答案 2 :(得分:0)

无论哪个线程首先发出锁定都会获胜。第二个线程将等到第一个线程释放锁定。

答案 3 :(得分:0)

'if'和'try'之间存在不同类型的竞争条件。例如,如果线程在其间中止,则它会使代码段被锁定。我不认为这是你的问题的重点,但那里仍然存在问题。