- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
Java内存模型
内存模型 (memory model)内存模型描述的是程序中各变量(实例域、静态域和数组元素)之间的关系,以及在实际计算机系统中将变量存储到内存和从内存取出变量这样的低层细节.不同平台间的处理器架构将直接影响内存模型的结构.在C或C++中, 可以利用不同操作平台下的内存模型来编写并发程序. 但是, 这带给开发人员的是, 更高的学习成本.相比之下, java利用了自身虚拟机的优势, 使内存模型不束缚于具体的处理器架构, 真正实现了跨平台.(针对hotspot jvm, jrockit等不同的jvm, 内存模型也会不相同)内存模型的特征:a, Visibility 可视性 (多核,多线程间数据的共享)b, Ordering 有序性 (对内存进行的操作应该是有序的)java 内存模型 (java memory model)根据Java Language Specification中的说明, jvm系统中存在一个主内存(Main Memory或Java Heap Memory),Java中所有变量都储存在主存中,对于所有线程都是共享的。每条线程都有自己的工作内存(Working Memory),工作内存中保存的是主存中某些变量的拷贝,线程对所有变量的操作都是在工作内存中进行,线程之间无法相互直接访问,变量传递均需要通过主存完成。
其中, 工作内存里的变量, 在多核处理器下, 将大部分储存于处理器高速缓存中, 高速缓存在不经过内存时, 也是不可见的.jmm怎么体现 可视性(Visibility) ?在jmm中, 通过并发线程修改变量值, 必须将线程变量同步回主存后, 其他线程才能访问到.jmm怎么体现 有序性(Ordering) ? 通过java提供的同步机制或volatile关键字, 来保证内存的访问顺序.
缓存一致性(cache coherency)什么是缓存一致性?它是一种管理多处理器系统的高速缓存区结构,其可以保证数据在高速缓存区到内存的传输中不会丢失或重复。举例理解:假如有一个处理器有一个更新了的变量值位于其缓存中,但还没有被写入主内存,这样别的处理器就可能会看不到这个更新的值.解决缓存一致性的方法?a, 顺序一致性模型:要求某处理器对所改变的变量值立即进行传播, 并确保该值被所有处理器接受后, 才能继续执行其他指令.b, 释放一致性模型: (类似jmm cache coherency)允许处理器将改变的变量值延迟到释放锁时才进行传播.
jmm缓存一致性模型 - happens-before ordering(先行发生排序)一般情况下的示例程序:x = 0;
y = 0;
i = 0;
j = 0;
// thread A
y = 1;
x = 1;
// thread B
i = x;
j = y;
在如上程序中, 如果线程A,B在无保障情况下运行, 那么i,j各会是什么值呢?答案是, 不确定. (00,01,10,11都有可能出现)这里没有使用java同步机制, 所以 jmm 有序性和可视性 都无法得到保障.happens-before ordering(先行发生排序)如何避免这种情况?排序原则已经做到:a, 在程序顺序中, 线程中的每一个操作, 发生在当前操作后面将要出现的每一个操作之前.b, 对象监视器的解锁发生在等待获取对象锁的线程之前.c, 对volitile关键字修饰的变量写入操作, 发生在对该变量的读取之前.d, 对一个线程的 Thread.start() 调用 发生在启动的线程中的所有操作之前.e, 线程中的所有操作 发生在从这个线程的 Thread.join()成功返回的所有其他线程之前.为了实现happends-before ordering原则, java及jdk提供的工具:a, synchronized关键字b, volatile关键字c, final变量d, java.util.concurrent.locks包(since jdk 1.5)e, java.util.concurrent.atmoic包(since jdk 1.5)...使用了happens-before ordering的例子:(1) 获取对象监视器的锁(lock)(2) 清空工作内存数据, 从主存复制变量到当前工作内存, 即同步数据 (read and load)(3) 执行代码,改变共享变量值 (use and assign)(4) 将工作内存数据刷回主存 (store and write)(5) 释放对象监视器的锁 (unlock)注意: 其中4,5两步是同时进行的.这边最核心的就是第二步, 他同步了主内存,即前一个线程对变量改动的结果,可以被当前线程获知
文档评论(0)