我正在看这个msdn关于与Monitor.Pulse()的线程同步的页面上的示例2。生产者 - 消费者示例,都在锁(此)块
Cell对象被创建并传递给生产者和消费者对象。
Cell cell = new Cell();
CellProd prod = new CellProd(cell, 20);
CellCons cons = new CellCons(cell, 20);
一个线程的每一个这两个
Thread producer = new Thread(new ThreadStart(prod.ThreadRun));
Thread consumer = new Thread(new ThreadStart(cons.ThreadRun));
创建的ThreadRun在每种情况下一个循环,调用Cell.ReadFromCell()或Cell.WriteToCell(),取决于消费者/生产者。例如,制作者这
public void ThreadRun()
{
for(int looper=1; looper<=quantity; looper++)
cell.WriteToCell(looper); // "producing"
}
我不明白的一点是,在每一种方法,他们开始用
lock(this)
而且由于它是一样的Cell对象(即,上面的锁定语句中的'this')传递给两者,我一直以为只有一个线程可以在这段代码中。然而,从Monitor.Pulse()和Monitor.Wait()后面的代码看来,这两个线程同时在这些部分中。如果有人拥有该锁,并且击中了一个Monitor.Wait(),那么另一个线程就永远不会Pulse,因为它被阻塞等待锁定。
我猜测有一个简单的解决方案,我误解了一些东西,从我的测试运行代码它看起来像两个线程同时在他们的关键部分,所以锁(这)不是做我应该做的印象。
请注意,这是一种糟糕的编程习惯来“锁定(this)”。相反,创建一个类型为object的私有字段并对其进行锁定。这是一个不好的做法,因为*任何人*都可以锁定该对象;如果您的锁定订单保证仅取决于*内部的代码*可以锁定的类型然后锁定这会使代码变得脆弱而难以分析。锁定私钥意味着你知道*只有*可以获得对私钥对象的引用的代码才能取出锁。 –
Eric,我完全同意,但MSDN不应该首先提供这样的示例代码。大多数时候,人们使用'lock(this)'语句是因为他们认为如果它在MSDN上,它必须是正确的方法。有没有办法提交更新MSDN内容的请求? – SolutionYogi
@SolutionYogi:好点。我会将其提请文档管理员注意。谢谢! –