您所说的同花大顺被称为“内存屏障”。这意味着CPU确保从其他CPU /内核也可以看到RAM的内容。它意味着两件事:
JIT编译器刷新CPU寄存器。通常,代码可以在CPU寄存器中保留一些全局可见数据(例如,实例字段内容)的副本。从其他线程看不到寄存器。因此,一半的工作
synchronized
是确保不维护此类缓存。该
synchronized
实现还执行内存屏障,以确保将当前内核对RAM的所有更改都传播到主RAM(或者至少所有其他内核都知道该内核具有最新值-缓存一致性协议可以是复杂)。
在单处理器系统(我的意思是,具有单个CPU且具有单核的系统)上,第二项工作是微不足道的,但是单处理器系统在当今变得越来越罕见。
对于线程局部堆,理论上可以做到这一点,但是通常不值得付出努力,因为没有任何东西可以告诉您要使用a刷新内存的哪些部分
synchronized。这是带共享内存的线程模型的局限性:应该共享
所有 内存。第一次遇到
synchronizedJVM时,应将其所有“线程本地堆对象”刷新到主RAM。
但是,Sun最近提供的JVM可以执行“转义分析”,其中JVM成功地证明了某些实例永远不会从其他线程中看到。例如,这是
StringBuilder创建
javac用于处理字符串串联的实例的典型方法。如果实例从不作为参数传递给其他方法,则它不会变为“全局可见”。这使它有资格进行线程本地堆分配,甚至在适当的情况下也有资格进行基于堆栈的分配。请注意,在这种情况下,没有重复。该实例不在“同时位于两个地方”。只是JVM可以将实例保留在私有位置,而不会产生内存屏障的成本。



