gpt4 book ai didi

c# - 如果我有条件地 Monitor.Enter 而另一个线程在没有锁的临界区中,会发生什么情况?

转载 作者:行者123 更新时间:2023-11-30 22:05:02 26 4
gpt4 key购买 nike

我正在尝试从系统类 (Lazy<T>) 重新实现功能,但我发现了这段不寻常的代码。我明白了基本的想法。第一个尝试获取值的线程执行计算。发生这种情况时尝试的任何线程都被锁定在门口,等到释放,然后去获取缓存的值。以后的任何调用都会注意到哨兵值,而不必再为锁烦恼。

bool lockWasTaken = false;
var obj = Volatile.Read<object>(ref this._locker);
object returnValue = null;

try
{
if (obj != SENTINEL_VALUE)
{
Monitor.Enter(obj, ref lockWasTaken);
}

if (this.cachedValue != null) // always true after code has run once
{
returnValue = this.cachedValue;
}
else //only happens on the first thread to lock and enter
{
returnValue = SomeCalculations();
this.cachedValue = returnValue;
Volatile.Write<object>(ref this._locker, SENTINEL_VALUE);
}
return returnValue
}
finally
{
if (lockWasTaken)
{
Monitor.Exit(obj);
}
}

但假设在更改代码后,另一种方法重置了 this._locker到它的原始值,然后进入锁定并重新计算缓存值。当它这样做时,另一个线程恰好正在获取缓存的值,因此它在锁定的部分内,但没有锁定。会发生什么?是否只是正常执行,而带锁的线程也并行执行?

最佳答案

While it does this, another thread happened to be picking up the cached value, so it's inside the locked section, but without a lock. What happens? Does it just execute normally while the thread with the lock also goes in parallel?

是的,它会正常执行。

话虽如此,这段代码似乎可以通过使用 Lazy<T> 完全删除。 . Lazy<T>类提供了一种线程安全的方式来处理数据的惰性实例化,这似乎是这段代码的目标。

基本上,整个代码可以替换为:

// Have a field like the following:
Lazy<object> cachedValue = new Lazy<object>(() => SomeCalculations());

// Code then becomes:
return cachedValue.Value;

关于c# - 如果我有条件地 Monitor.Enter 而另一个线程在没有锁的临界区中,会发生什么情况?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24661042/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com