如果有多个线程在同一个锁上等待,则可以让主线程获得锁定具有更高的优先级。这意味着如果工作线程在主线程之前转到lock
语句,主线程将在已经等待它的其他线程之前获取锁。
答案 0 :(得分:7)
不,lock
语句映射到System.Threading.Monitor.Enter()
(MSDN),并且没有接受优先级参数的重载。
我能想到的最接近的是ReaderWriterLock(Slim),但我会认真重新考虑导致此请求的设计。可能有更好的方法来实现您的需求。
答案 1 :(得分:2)
通过本机锁定语句,没有。通过您自己的自定义锁定机制,当然,如果您愿意花时间和精力来开发它。
这是我的草案解决方案。它可能有效也可能无效,可能效率不高,但它至少是一个起点:
public class Lock
{
bool locked = false;
private object key = new object();
SortedDictionary<int, Queue<ManualResetEvent>> notifiers =
new SortedDictionary<int, Queue<ManualResetEvent>>();
ManualResetEvent specialNotifier = null;
public void Lock()
{
lock (key)
{
if (locked)
{
ManualResetEvent notifier = new ManualResetEvent(false);
int priority = getPriorityForThread();
Queue<ManualResetEvent> queue = notifiers[priority];
if (queue == null)
{
queue = new Queue<ManualResetEvent>();
notifiers[priority] = queue;
}
queue.Enqueue(notifier);
notifier.WaitOne();
}
else
{
locked = true;
}
}
}
private static int getPriorityForThread()
{
return 0;
}
public void Release()
{
lock (key)
{
foreach (var queue in notifiers.Values)
{
if (queue.Any())
{
var notifier = queue.Dequeue();
notifier.Set();
return;
}
}
locked = false;
}
}
}
答案 2 :(得分:1)
这是另一种解决方案。我有很多行,但很简单。函数DoSomethingSingle
一次只能被调用一个线程,而highPriority
标志的那个将获得优先权。
static int numWaiting = 0;
static object single = new object();
ResultType DoSomething(string[] argList, bool highPriority = false)
{
try
{
if (highPriority)
{
Interlocked.Increment(ref numWaiting);
}
for (;;)
{
lock (single)
{
if (highPriority || numWaiting == 0)
{
return DoSomethingSingle(argList);
}
}
// Sleep gives other threads a chance to enter the lock
Thread.Sleep(0);
}
}
finally
{
if (highPriority)
{
Interlocked.Decrement(ref numWaiting);
}
}
}
这允许两个优先级。保证只有在没有高优先级线程等待它时,低优先级线程才能访问资源。
编辑:更改为互锁incr / dec