我理解升级锁试图解决经典死锁的例子,其中两个并发线程持有读锁并试图获取写锁将死锁。
线程A: S锁(已获取)
线程B: S锁(已获取)
线程A: X锁(等待线程B释放S锁)
线程B: X锁(等待A释放S锁)DEADLOCKED
为什么升级锁没有同样的问题?该文档说,只有一个线程可以被授予升级锁,并且允许在其他线程仍然持有S锁的情况下这样做。有人能解释一下为什么运行此模式的两个并发线程不会陷入死锁吗?
lock.AcquireSharedLock() // Thread A and B both acquired this S lock
lock.EnterUpgradeableReadLock(); // Only one (e.g. A) acquired U lock and other (e.g. B) is blocked here.
if(somecondition)
{
lock.AcquireExclusiveLock(); // A tries to acquire X lock. But wouldn't it get blocked since B is already holding onto S lock? B is already blocked, so this has to be a deadlock
}
有趣的是,我刚刚回答了SQL Server和UPDATE
语句的相同问题:UPDATE锁如何防止常见形式的死锁?
答案的关键方面是可升级事务从不使用s锁。他们立即u型锁。因此,s锁和x锁之间永远不会有冲突。
在你的例子中,
lock.AcquireSharedLock()
不应该存在。您可以 S-lock 或 U-lock。