中国开发网: 论坛: 程序员情感CBD: 贴子 651679
龙之吻
有点晕
不仅如此(构造函数与 instance 变量赋值的顺序完全取决于编译器实现),编译器产生的代码也可能被CPU再次做乱序和并行(out-of-order / parallelism)优化。现代CPU,包括各款奔腾在内,都使用乱序和并行来尽量避免流水线等待内存,IO,以提高执行效率。

另外,一个像样的CPU,是不会把那个 TEMP 写到内存里,再回头花费几百个 CPU CLOCK 从内存里拿回来,赋值给 m_instance 寄存器,然后再把 m_instance 写回内存的。其实远远不到 CPU 的层面,编译器已经会发现这样很不核算从而通通优化调。即使编译器不优化,CPU也不会这么做,而是把m_instance写到缓存里。既然牵扯到缓存,如果你有两个以上的物理CPU,或者两个以上的物理内核,或者两个以上的虚拟内核(所谓超线程),就不能保证各个执行单元看到的是一个值,除非用 synchronized{} 告诉 JVM 需要作 同步/缓存提交。

总而言之,在 JAVA 5 之前的JAVA 内存模型下,如果使用优化编译器,或者使用了并行架构的硬件,那么DCL是“不保证正确”的,无论用什么办法修改,就好像永动机不可能实现一样。

好消息是:包含在 JAVA 5 的 JSR 133 之下,如果把 m_instance 改为 volatile 变量,那么DCL至少是“功能正确”的。因为 JSR 133 更改了 volatile 的语义,使 volatile 变量的读写与 synchronized 有相当的涵义。

坏消息是:如果把 m_instance 改为 volatile 变量,那么DCL虽然功能正确,效率却和在 synchronized block 内部单一检查完全一样,甚至更差一点(因为检查了两次)。所以,DCL 就完全不具有物理意义了。

再次总而言之,DCL 在 JAVA 是没有价值的。值得一提的是,DCL在 C# 里也同样没有意义。抄的就是抄的,连 BUG 都一起抄去了。呵呵。

不过老板关于SPRING的评价在这里并不合乎语境。如果我的需求必须计较 SYNCHRONIZED 所带来的几百个 CPU CLOCK 的性能损失,又怎么可能容忍 XML PARSING 和 REFLECTION?


机器人,这首歌学会了没有?

我们的目标是->没有蛀牙!

相关信息:


欢迎光临本社区,您还没有登录,不能发贴子。请在 这里登录