CLR是否执行"锁定省略"优化?如果不是为什么不呢?

chi*_*tom 9 .net java clr multithreading locking

JVM执行一个称为锁定省略的巧妙技巧,以避免锁定仅对一个线程可见的对象的成本.

这里有一个很好的描述:

http://www.ibm.com/developerworks/java/library/j-jtp10185/

.Net CLR是否有类似的功能?如果不是那么为什么不呢?

Cod*_*aos 8

它很整洁,但有用吗?我很难想出一个例子,编译器可以证明锁是本地线程的.默认情况下,几乎所有类都不使用锁定,当您选择锁定时,在大多数情况下,它会从某种静态变量引用,无论如何都会阻碍编译器优化.

另一件事是java vm在其证明中使用了逃逸分析.而AFAIK .net尚未实施逃逸分析.转义分析的其他用途,例如用堆栈分配替换堆分配听起来更有用,应该首先实现.

IMO目前不值得编码..net VM中有许多区域没有很好地优化并且具有更大的影响.

SSE向量指令和委托内联是两个示例,我的代码从这个示例中获益远远超过此优化.


Jon*_*eet 5

编辑:正如 chibacity 在下面指出的,这是在谈论使锁真正便宜而不是完全消除它们。我不相信JIT 有“线程局部对象”的概念,尽管我可能会误会......即使现在没有,当然将来也可能会出现。

编辑:好的,下面的解释过于简化,但至少有一些现实基础:) 有关更详细的信息,请参阅Joe Duffy 的博客文章


我不记得我在哪里读到的——可能是“CLR via C#”或“Concurrent Programming on Windows”——但我相信CLR 只会在需要时才懒惰地将同步块分配给对象。当监视器从未被竞争的对象被锁定时,对象头会自动更新为比较交换操作,表示“我被锁定了”。如果另一个线程随后尝试获取锁,CLR 将能够确定它已经被锁定,并且基本上将该锁升级为“完整”锁,为其分配一个同步块。

当一个对象有一个“完全”锁时,锁定操作比锁定和解锁一个没有其他问题的对象更昂贵。

如果我对此是正确的(并且它是一个非常模糊的记忆),那么廉价地锁定和解锁不同线程上的监视器应该是可行的,只要锁定永远不会重叠(即没有争用)。

我会看看我是否可以为此挖掘一些证据......