[英]C# Does an empty lock block get “optimized” away?
我找不到有关 C# 编译器或 JIT 是否会删除内部没有代码的锁定语句的任何信息。 这会始终生成并执行Monitor.Enter
和Monitor.Exit
调用吗?
lock(lockObj) { }
我正在尝试做的一个(大大简化的)版本(是的,我知道在锁中调用回调是不好的):
public class ExecutionSource
{
private List<Action<object>> _callbacks = new List<Action<object>>();
private object _value;
public void AddListener(Action<object> listener)
{
object temp = _value;
if (temp != null)
{
listener(temp);
return;
}
lock (_callbacks)
{
temp = _value;
if (temp != null)
{
listener(temp);
}
else
{
_callbacks.Add(listener);
}
}
}
public void Execute(object value)
{
if (value == null) throw new InvalidOperationException("value must be non-null");
if (Interlocked.CompareExchange(ref _value, value, null) != null)
{
throw new InvalidOperationException("Can only execute once.");
}
lock (_callbacks) { } // Wait for a listener that is currently being added on another thread. No need to lock the entire loop.
foreach (var callback in _callbacks)
{
callback(value);
}
_callbacks.Clear();
}
}
不,他们没有。 CLI 不能假设没有其他线程已经锁定了 object。
如果任何其他线程(或您当前的代码)尝试使用非零线程锁定Monitor.Enter/Exit
,如果需要,它将 go 进入旋转等待或提升到基于 kernel 的事件。
对于它的价值,因为您不关心重新排序,并且根据您的用例是什么,可能有其他同步原语可能更适合您的特定用例。 像重置事件等。
根据sharplib ,我们可以看到编译器不会删除空锁块。 此外,我无法想象我们如何在真正的多线程环境中在编译时对其进行优化,并确保我们不会破坏任何东西。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.