锁(变量)-变量的冲突解释

本文关键字:变量 冲突 解释 | 更新日期: 2023-09-27 18:09:55

文档没有解释。他们只说什么应该锁定,什么不应该锁定。

从这里看来,所有线程都应该使用相同的对象来锁。而从这里看来,这正是应该避免的,以防止死锁。

请记住,我可能误解了锁的整个问题,因为我刚刚问了一个关于如何"锁定"变量的问题,并得到了在我看来根本无法实现的(除了锁定代码)。

锁(变量)-变量的冲突解释

可以把锁想象成在某些会议中使用的"谈话棒"。拿着棍子的人可以说话。任何想说话的人都必须等到说话者放下棍子。

当一段代码获得对象上的锁时,任何其他请求同一对象上的锁的代码必须等待,直到原始代码释放锁。

那么应该锁定哪个对象呢?这在很大程度上取决于语境。经验法则是您锁定的对象任何可能影响代码块的人都可以锁定该对象。如果您正在更新一个集合,那么您可以以ICollection.SyncRoot为例。

编辑由OP (希望正确): "任何想说话的人"-作为"那根棍子"的演讲者。(任何人都可以说话。)至于问题中的第二个链接——它指的是一个锁等待第二个锁,而第二个锁等待第一个锁的问题。

lock应该用于任何共享资源。我所说的"共享资源"是指任何可以被多个线程访问的资源。

锁的作用是:

  1. 传入线程想要访问一段代码,遇到锁
  2. 锁为空,允许线程进入
  3. 线程被切换出
  4. 另一个线程想要访问相同的代码(或锁定在同一变量上的代码),遇到锁
  5. 变量已经锁定,线程必须等待
  6. 原线程切换回,退出锁定代码
  7. 第二个线程切换回,执行锁定的代码
如果一个锁中的线程可能同时等待另一个锁,然后等待第一个锁,那么就会出现gridlock条件。通常情况下,您不会"嵌套"您的锁以避免此问题。另外,如果不考虑其他因素的话,为了提高性能,您很少将同一个变量锁定为另一个变量,除非您的两个变量都依赖于不能并发执行的代码(如果是这样的话,可能是一个糟糕的设计:)

锁定对象是为了保护共享内存。所以,你必须对你要保护的特定元素使用相同的SyncRoot…但是,假设您有3个需要保护的对象,并且它们之间没有任何关联:

A a = new A();
B b = new B();
C c = new C();

则没有理由对所有3个使用相同的SyncRoot。事实上,如果它们真的是分开的,那将是低效的。