seman198102 2009-09-10 15:21
浏览 325
已采纳

为什么线程要保存共享成员变量的私有拷贝?

"Java语言规范中指出:为了获得最佳速度,允许线程保存共享成员变量的私有拷贝,而且只当线程进入或者离开同步代码块时才与共享成员变量的原始值对比。"
为什么保存私有拷贝,速度就能提升呢?
还有,这个私有拷贝保存在哪里?frame中的local variable吗?
如果这个共享成员是非primitive的对象,那是不是还要在heap中深克隆这个对象吗?

[b]问题补充:[/b]
"每条线程都有自己的工作内存(Working Memory),工作内存中保存的是主存中某些变量的拷贝,线程对所有变量的操作都是在工作内存中进行,线程之间无法相互直接访问,变量传递均需要通过主存完成。"
JVM的内存模型需要考虑cpu的缓存吗?我以为JVM为每条线程创建的工作内存也是在内存上,所以我就不明白为什么要copy一分到工作内存以提高性能?

  • 写回答

3条回答 默认 最新

  • rednaxelafx 2009-09-10 16:10
    关注

    因为概念上是“一份”的内存实际上未必只有一份……
    假象下述情况:一个对象被两个线程共享,而这两个线程分别在两个核上同时执行,并且两个核的L1和L2缓存不共享;在“主内存”里,该对象只有一份,但CPU要读取数据需要先把它读到缓存里,因为对数据的访问通常表现出“局部性”,而且缓存速度比主内存快很多,所以这样在许多时候比较快;数据经过了主内存->L2缓存->L1缓存,然后才到CPU进行运算。某个核的缓存不flush到主内存的时候,别的核“看不到”相应的更新;并且,别的核如果不强制从主内存重新读数据到缓存里的话,它也“不去看”相应的更新。于是,如果不做特别的处理,线程间就有可能看到状态不一致的共享数据了。主内存与缓存间的复制关系,就是字节对字节的复制而已,并没有刻意的深拷贝。

    Java 5更新了内存模型的规定后,收紧了volatile-read和volatile-write的语义,可以去看看相关资料。

    [quote="seman18"]还有,这个私有拷贝保存在哪里?frame中的local variable吗?[/quote]
    如果你说的“frame”是指JVM规范里关于Java方法调用的frame的话,你可能把不同抽象层次的概念混在一起了。JVM规范里的frame具体要如何实现并不是规范所关心的。事实上frame可能不是整体保存在一个地方,可以一部分在寄存器里一部分在栈上,或者整个在堆上,都没有关系,只要表明上的行为满足规范的规定就行。从这个抽象层次上是涉及不到底下的硬件处理多线程时会遇到的问题的……

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥20 delta降尺度方法,未来数据怎么降尺度
  • ¥15 c# 使用NPOI快速将datatable数据导入excel中指定sheet,要求快速高效
  • ¥15 再不同版本的系统上,TCP传输速度不一致
  • ¥15 高德地图点聚合中Marker的位置无法实时更新
  • ¥15 DIFY API Endpoint 问题。
  • ¥20 sub地址DHCP问题
  • ¥15 delta降尺度计算的一些细节,有偿
  • ¥15 Arduino红外遥控代码有问题
  • ¥15 数值计算离散正交多项式
  • ¥30 数值计算均差系数编程