Answers:
该lock
语句由C#3.0转换为以下内容:
var temp = obj;
Monitor.Enter(temp);
try
{
// body
}
finally
{
Monitor.Exit(temp);
}
在C#4.0中,此更改已更改,现在生成如下:
bool lockWasTaken = false;
var temp = obj;
try
{
Monitor.Enter(temp, ref lockWasTaken);
// body
}
finally
{
if (lockWasTaken)
{
Monitor.Exit(temp);
}
}
你可以找到什么更多信息Monitor.Enter
确实在这里。引用MSDN:
使用
Enter
以获取作为参数传递的对象上的监视器。如果另一个线程Enter
在对象上执行,但尚未执行Exit
,则当前线程将阻塞,直到另一个线程释放对象。同一线程在Enter
不阻塞的情况下多次调用是合法的 。但是,Exit
必须等待相等数量的 调用,然后等待该对象的其他线程才能解除阻塞。
该Monitor.Enter
方法将无限期等待;它不会超时。
obj
而不会导致整个系统陷入僵局。
lock
-statement和Monitor 的全部目的:这样,您可以在一个线程中执行操作,而不必担心另一个线程会将其破坏。
它比您想象的要简单。
根据Microsoft的说法:lock
关键字确保一个线程不会输入代码的关键部分,而另一个线程在关键部分。如果另一个线程试图输入锁定的代码,它将等待阻塞,直到对象被释放为止。
该lock
关键字要求Enter
在该块的开始和Exit
在块的结尾。lock
关键字实际上Monitor
在后端处理类。
例如:
private static readonly Object obj = new Object();
lock (obj)
{
// critical section
}
在上面的代码中,首先线程进入关键部分,然后将其锁定obj
。当另一个线程尝试进入时,它还将尝试锁定obj
已被第一个线程锁定的。第二个线程将必须等待第一个线程释放obj
。当第一个线程离开时,然后另一个线程将锁定obj
并进入关键部分。
不,他们没有排队,他们正在睡觉
形式的锁语句
lock (x) ...
其中x是引用类型的表达式,精确等于
var temp = x;
System.Threading.Monitor.Enter(temp);
try { ... }
finally { System.Threading.Monitor.Exit(temp); }
您只需要知道它们正在互相等待,只有一个线程进入锁定块,其他线程将等待...
lock
声明小幅C#4变:blogs.msdn.com/b/ericlippert/archive/2009/03/06/...
对性能的影响取决于锁定方式。您可以在此处找到良好的优化列表:http : //www.thinkingparallel.com/2007/07/31/10-ways-to-reduce-lock-contention-in-threaded-programs/
基本上,您应该尝试尽可能少地锁定,因为这会使您的等待代码进入休眠状态。如果您在锁定中进行了繁重的计算或持久的代码(例如文件上传),则会导致巨大的性能损失。
do { oldValue = thing; newValue = updated(oldValue); } while (CompareExchange(ref thing, newValue, oldValue) != oldValue
]。最大的危险是,如果需求超出了此类技术可以处理的范围,则可能很难修改代码来处理该技术。