Does lock() guarantee acquired in order requested?(lock() 是否保证按请求的顺序获得?)
问题描述
当多个线程请求同一个对象上的锁时,CLR 是否保证将按照它们被请求的顺序获取锁?
When multiple threads request a lock on the same object, does the CLR guarantee that the locks will be acquired in the order they were requested?
我写了一个测试看看这是不是真的,它似乎表明是的,但我不确定这是否是确定的.
I wrote up a test to see if this was true, and it seems to indicate yes, but I'm not sure if this is definitive.
class LockSequence
{
private static readonly object _lock = new object();
private static DateTime _dueTime;
public static void Test()
{
var states = new List<State>();
_dueTime = DateTime.Now.AddSeconds(5);
for (int i = 0; i < 10; i++)
{
var state = new State {Index = i};
ThreadPool.QueueUserWorkItem(Go, state);
states.Add(state);
Thread.Sleep(100);
}
states.ForEach(s => s.Sync.WaitOne());
states.ForEach(s => s.Sync.Close());
}
private static void Go(object state)
{
var s = (State) state;
Console.WriteLine("Go entered: " + s.Index);
lock (_lock)
{
Console.WriteLine("{0,2} got lock", s.Index);
if (_dueTime > DateTime.Now)
{
var time = _dueTime - DateTime.Now;
Console.WriteLine("{0,2} sleeping for {1} ticks", s.Index, time.Ticks);
Thread.Sleep(time);
}
Console.WriteLine("{0,2} exiting lock", s.Index);
}
s.Sync.Set();
}
private class State
{
public int Index;
public readonly ManualResetEvent Sync = new ManualResetEvent(false);
}
}
打印:
进入:0
0 被锁定
0 睡眠 49979998 滴答
0 sleeping for 49979998 ticks
进入:1
进入:2
进入:3
进入:4
进入:5
进入:6
进入:7
进入:8
进入:9
0 退出锁定
1 被锁定
1 睡眠 5001 滴答声
1 sleeping for 5001 ticks
1 个退出锁
2 被锁定
2 睡眠 5001 滴答声
2 sleeping for 5001 ticks
2 退出锁
3 被锁定
3 睡眠 5001 滴答声
3 sleeping for 5001 ticks
3 退出锁
4 被锁定
4 睡眠 5001 滴答声
4 sleeping for 5001 ticks
4 退出锁
5 被锁定
5 睡眠 5001 滴答声
5 sleeping for 5001 ticks
5 退出锁
6 被锁定
6 退出锁
7 被锁定
7 退出锁
8 被锁定
8 退出锁
9 被锁定
9 退出锁
推荐答案
IIRC,很有可能按这个顺序排列,但不能保证.我相信至少在理论上存在一个线程会被虚假唤醒的情况,注意它仍然没有锁,然后走到队列的后面.这可能仅适用于 Wait
/Notify
,但我偷偷怀疑它也适用于锁定.
IIRC, it's highly likely to be in that order, but it's not guaranteed. I believe there are at least theoretically cases where a thread will be woken spuriously, note that it still doesn't have the lock, and go to the back of the queue. It's possible that's only for Wait
/Notify
, but I have a sneaking suspicion it's for locking as well.
我肯定不会依赖它 - 如果您需要按顺序发生,请建立一个 Queue<T>
或类似的东西.
I definitely wouldn't rely on it - if you need things to occur in a sequence, build up a Queue<T>
or something similar.
我刚刚在 Joe Duffy 的 Concurrent基本同意的Windows编程:
I've just found this within Joe Duffy's Concurrent Programming on Windows which basically agrees:
因为监视器在内部使用内核对象,所以它们表现出与操作系统同步机制也表现出的大致相同的 FIFO 行为(在前一章中描述).监视器是不公平的,因此如果另一个线程在唤醒的等待线程尝试获取锁之前尝试获取锁,则允许偷偷摸摸的线程获取锁.
Because monitors use kernel objects internally, they exhibit the same roughly-FIFO behavior that the OS synchronization mechanisms also exhibit (described in the previous chapter). Monitors are unfair, so if another thread tries to acquire the lock before an awakened waiting thread tries to acquire the lock, the sneaky thread is permitted to acquire a lock.
大致 FIFO"位是我之前想到的,而偷偷摸摸的线程"位进一步证明了您不应该对 FIFO 排序做出假设.
The "roughly-FIFO" bit is what I was thinking of before, and the "sneaky thread" bit is further evidence that you shouldn't make assumptions about FIFO ordering.
这篇关于lock() 是否保证按请求的顺序获得?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:lock() 是否保证按请求的顺序获得?
基础教程推荐
- 如何激活MC67中的红灯 2022-01-01
- SSE 浮点算术是否可重现? 2022-01-01
- 有没有办法忽略 2GB 文件上传的 maxRequestLength 限制? 2022-01-01
- 为什么Flurl.Http DownloadFileAsync/Http客户端GetAsync需要 2022-09-30
- rabbitmq 的 REST API 2022-01-01
- 如何在 IDE 中获取 Xamarin Studio C# 输出? 2022-01-01
- 将 XML 转换为通用列表 2022-01-01
- MS Visual Studio .NET 的替代品 2022-01-01
- 将 Office 安装到 Windows 容器 (servercore:ltsc2019) 失败,错误代码为 17002 2022-01-01
- c# Math.Sqrt 实现 2022-01-01