快速业务通道

Java理论与实践: 修复Java内存模型,第2部分 - 编程入门网

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-06-22

Java理论与实践: 修复Java内存模型,第2部分

时间:2010-12-20 IBM Brian Goetz

活跃了将近三年的 JSR 133,近期发布了关于如何修复 Java 内存模型 (Java Memory Model, JMM)的公开建议。在本系列文章的 第 1 部分,专栏作 者 Brian Goetz 主要介绍最初的 JMM 中的几个严重缺陷,这些缺陷导致了一些 难度高得惊人的概念语义,这些概念原来被认为很简单。这个月,他介绍在新 JMM 中 volatile 和 final 的语义是如何变化的,这些改变使它们的语义符合 大多数开发人员的直觉。其中一些改变已经在 JDK 1.4 中出现了,另一些改变 则要等到 JDK 1.5。请您在本文的讨论论坛上与作者及其他读者交流您的想法。

开始编写并发代码是一件困难的事情,语言不应当增加它的难度。虽然 Java 平台从一开始就包括了对线程的支持,包括一个计划为正确同步的程序提供“一 次编写,到处运行”保证的、跨平台的内存模型,但是原来的内存模型有一些漏 洞。虽然许多 Java 平台提供了比 JMM 所要求的更强的保证,但是 JMM 中的漏 洞使得无法容易地编写可以在任何平台上运行的并发 Java 程序。所以在 2001 年 5 月,成立了以修复 Java 内存模型为目的的 JSR 133。 上个月,我讨论了 其中一些漏洞,这个月,我们将讨论如何堵住它们。

修复后的可见性

理解 JMM 所需要的一个关键概念是 可见性(visibility)——如何知道当 线程 A 执行 someVariable?=?3 时,其他线程是否可以看到线程 A 所写的值 3 ?有一些原因使其他线程不能立即看到 someVariable 的值 3:可能是因为编译 器为了执行效率更高而重新排序了指令,也可能是 someVariable 缓存在寄存器 中,或者它的值写到写处理器的缓存中、但是还没有刷新到主存中,或者在读处 理器的缓存中有一个老的(或者无效的)值。内存模型决定什么时候一个线程可 以可靠地“看到”由其他线程对变量的写入。特别是,内存模型定义了保证内存 操作跨线程的可见性的 volatile 、 synchronized 和 final 的语义。

当线程为释放相关监视器而退出一个同步块时,JMM 要求本地处理器缓冲刷 新到主存中。(实际上,内存模型不涉及缓存——它涉及一个抽象( 本地内存 ), 它包围了缓存、注册表和其他硬件和编译优化。)与此类似,作为获得监视 的一部分,当进入一个同步块时,本地缓存失效,使之后的读操作直接进入主内 存而不是本地缓存。这一过程保证当变量是由一个线程在由给定监视器保护的同 步块中写入,并由另一个线程在由同一监视器保护的同步块中读取时,对变量的 写可被读线程看到。如果没有同步,则 JMM 不提供这种保证——这就是为什么 在多个线程访问同一个变量时,必须使用同步(或者它的更年轻的同胞 volatile )。

对 volatile 的新保证

volatile 原来的语义只保证 volatile 字段的读写直接在主存而不是寄存器 或者本地处理器缓存中进行,并且代表线程对 volatile 变量进行的这些操作是 按线程要求的顺序进行的。换句话说,这意味着老的内存模型只保证正在读或写 的变量的可见性,不保证写入其他变量的可见性。虽然可以容易实现它,但是它 没有像最初设想的那么有用。

虽然对 volatile 变量的读和写不能与对其他 volatile 变量的读和写一起 重新排序,但是它们仍然可以与对 nonvolatile 变量的读写一起重新排序。在 第 1 部分 中,介绍了清单 1 的代码(在旧的内存模型中)是如何不足以保证 线程 B 看到 configOptions 及通过 configOptions 间接可及的所有变量(如 Map 元素)的正确值,因为 configOptions 的初始化可能已经随 volatile initialized 变量进行重新排序。

清单 1. 用一个 volatile 变量作为“守护”

Map configOpti

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号