生产者 - 消费者示例,都在lock(this)块中

Pau*_*l M 2 c# multithreading

我在这个msdn页面上看了关于与Monitor.Pulse()进行线程同步的例2 .

创建Cell对象并将其传递给生产者和使用者对象.

Cell cell = new Cell( );
CellProd prod = new CellProd(cell, 20);
CellCons cons = new CellCons(cell, 20);
Run Code Online (Sandbox Code Playgroud)

为这两者中的每一个创建一个线程

Thread producer = new Thread(new ThreadStart(prod.ThreadRun));
Thread consumer = new Thread(new ThreadStart(cons.ThreadRun));
Run Code Online (Sandbox Code Playgroud)

ThreadRun在每种情况下都是一个循环,它根据消费者/生产者调用Cell.ReadFromCell()或Cell.WriteToCell().例如,生产者这样做

public void ThreadRun( )
{
  for(int looper=1; looper<=quantity; looper++)
     cell.WriteToCell(looper);  // "producing"
}
Run Code Online (Sandbox Code Playgroud)

我不明白的是,在每种方法中,它们都以a开头

lock(this)
Run Code Online (Sandbox Code Playgroud)

并且因为它是同一个Cell对象(即上面的锁定语句中的'this')传递给两者,我认为一次只有一个线程可以在这段代码中.然而,从它后面的Monitor.Pulse()和Monitor.Wait()代码看起来两个线程同时在这些部分中.如果有一个锁并且点击一个Monitor.Wait()那么另一个线程永远不会是Pulse,因为它被阻塞等待锁定.

我猜有一个简单的解决方案而且我误解了一些东西,从我运行代码的测试看起来两个线程同时在他们的关键部分,所以锁(这个)不是我做的事情它应该做的印象.

Jon*_*eet 8

你失踪的事情是,Monitor.Wait(this)释放上的锁this,直到它唤醒.所以,是的,你的消费者线程看起来像在锁中并因此拥有它,但实际上它是暂时释放的.

来自文档:

当一个线程调用Wait时,它释放对象的锁并进入对象的等待队列.对象的就绪队列中的下一个线程(如果有)获取锁并且独占使用该对象.所有调用Wait的线程都会保留在等待队列中,直到它们收到来自Lock的所有者发送的Pulse或PulseAll的信号.如果发送Pulse,则只有等待队列头部的线程受到影响.如果发送PulseAll,则等待该对象的所有线程都会受到影响.当接收到信号时,一个或多个线程离开等待队列并进入就绪队列.准备队列中的线程被允许重新获取锁.