我有几个线程之间共享的资源和以下使用模式:
线程1不断使用受保护资源。
线程2..N需要在很短的时间内与受保护资源进行交互。
我希望线程1能够持续保护资源,并在其工作周期的特定时间向其他线程等待轮到他们。如果没有其他线程正在等待,它应立即重新获取锁 并继续其工作。
我想有一种方法可以做到这一点:
lock (resource)
{
while (!stop)
{
resource.DoWorkIteration();
// give other threads a chance
Monitor.Exit(resource);
Thread.Sleep(0);
Monitor.Enter(resource);
}
}
然而,Sleep(0)将产生任何准备运行的线程,而不仅仅是等待这个特定资源的线程。
有没有更好的方法来避免不必要的屈服?
答案 0 :(得分:2)
这是一般建议,但您应该协调对它的访问,而不是竞争资源。原因是锁定,解锁和上下文切换的开销不可忽略,而且它总是存在死锁的危险。释放和重新获取锁也不是免费的,所以你最好避免使用它。
在你的情况下,我建议任何线程2..N需要完成资源实际上是由线程1完成。为此,使用存储在队列中的回调(最好是运行非阻塞的回调)。当队列为空时,线程1会自行执行操作,否则会从队列中弹出回调并执行它。如果需要结果,请使用请求线程等待的事件。也许你也可以利用.Net用来将非UI线程的调用委托给UI元素的现有系统。