如果我有以下代码:
lock(SyncRoot){ return value; }
在返回语句之前是否会解锁SyncRoot?
我试过浏览VS2005中的代码,但它实际上并没有显示出这样或那样的方式。它似乎解锁了,但我想确定。
答案 0 :(得分:3)
是的,无论你如何退出街区(即返回,休息,投掷等),它都会解锁。
有关详细信息,请参阅MSDN - lock statement:
lock关键字确保一个线程不进入代码的关键部分,而另一个线程处于临界区 ...
lock关键字在块的开头调用Enter,在 块结束。
答案 1 :(得分:3)
是的,你可以把它想象成这样的东西:
Monitor.Enter(obj);
try {
var result = value;
}
finally {
Monitor.Exit(obj);
}
return result;
如果你看一下生成的IL,就是这样的。如果value
是表达式,则会在释放锁之前对其进行评估。释放锁后执行返回。
在任何情况下都会调用finally块,所以是的,锁被释放。
答案 2 :(得分:2)
是的,它会计算值(如果值是一个表达式,这可能很重要),然后解锁并返回。无论你如何操作,当你退出其范围时,lock()总是自动解锁。
答案 3 :(得分:2)
请注意,lock
实际上在后台使用Monitor.Enter
/ Monitor.Exit
。您的代码的扩展版本实际上就是
Monitor.Enter (SyncRoot);
try
{
return value;
}
finally { Monitor.Exit (SyncRoot); }
保证finally
块在方法实际返回之前执行,因此锁被释放。
答案 4 :(得分:1)
块执行后会解锁。
此语法类似于using
,顺便说一句。 lock
在块之外的唯一原因是显示启动时锁定,结束时解锁功能。
答案 5 :(得分:1)
如果你有类似`的东西 int i = 0; object o = new object();
while (i < 100)
{
lock (o)
{
if (i == 10)
continue;
}
++i;
}`
这会导致死锁,因为 它将永远等待获得 锁定从上一次执行中保存 继续之前的上下文
答案 6 :(得分:0)
不,只有在返回语句后才会释放锁。