使用c#锁定共享数据

时间:2010-04-27 14:05:20

标签: c# multithreading locking

我有一个程序(C#),其中包含要执行的测试列表 另外,我有两个帖子。一个用于将任务添加到列表中,另一个用于读取和删除执行的任务 每当其中一个线程想要访问列表时,我就会使用'lock'函数 我想要做的另一件事是,如果列表为空,则需要从列表中读取的线程将会休眠。并在第一个线程将任务添加到列表时唤醒。 这是我写的代码:

...
List<String> myList = new List();
Thread writeThread, readThread;
writeThread = new Thread(write);
writeThread.Start();
readThraed = new Thread(read);
readThread.Start();
...
private void write()
{
   while(...)
   {
     ...
     lock(myList)
     {
        myList.Add(...);
     }
     ...
     if (!readThread.IsAlive)
     {
        readThraed = new Thread(read);
        readThread.Start();
     }
     ...
   }
   ...
}

private void read()
{
bool noMoreTasks = false;
   while (!noMoreTasks)
   {
      lock (MyList)//syncronize with the ADD func.
      {
                if (dataFromClientList.Count > 0)
                {
                    String task = myList.First();
                    myList.Remove(task);
                }
                else
                {
                    noMoreTasks = true;
                }      
      }
      ...
   }
   readThread.Abort();
}

显然我做错了,并没有按预期执行(readTread没有从列表中读取)。
有谁知道我的问题是什么,以及如何做到对不对? 非常感谢,

2 个答案:

答案 0 :(得分:3)

您需要的是阻塞队列。它就像一个普通的队列,除了Dequeue方法阻塞,如果没有任何排队。 Here是一种实现。一旦你实现了阻塞队列,那么其他一切都很容易。请注意您使用的阻塞队列的哪个实现。我看到很多例子都有微妙的线程问题。最好坚持我提供的链接。

public class Example
{
  private BlockingQueue<Task> m_Queue = new BlockingQueue<Task>();

  public void StartExample()
  {
    Thread producer = new Thread(() => Producer());
    Thread consumer = new Thread(() => Consumer());
    producer.Start();
    consumer.Start();
    producer.Join();
    consumer.Join();
  }

  private void Producer()
  {
    for (int i = 0; i < 10; i++)
    {
      m_Queue.Enqueue(new Task());
    }
  }

  private void Consumer()
  {
    while (true)
    {
      Task task = m_Queue.Dequeue();
    }
  }
}

答案 1 :(得分:2)

我建议你看看Jon Skeet的Producer Consumer example。 有关Producer Consumer的更多信息,请查看Wikipedia