与其他字段相比,final字段是不同的。例如,一个线程用final字段x读取一个“完全初始化”的对象;在对象“完全初始化”后,能保证读取了final字段y的初始值,但不能保证“正常”的非final字段nonX。
注:“完全初始化”是指对象的构造函数完成。
鉴于上述情况,有一些简单的事情可以在JMM9中修复。例如:volatile类型字段,volatile字段在构造函数中初始化是不保证可见性的,即使对实例本身是可见的。因此,问题来了,是否final字段应该保证扩大到所有字段,包括初始化volatile字段?此外,如果一个完全初始化对象的“正常”非final字段的值不发生变化,我们是否可以将final字段保证到这个“正常”的字段。
参考文献我从如下这些网站学到了很多,他们提供了大量的示例编码。本文是一篇介绍性的文章,以下文章更适合深入掌握Java内存模型。
JSR 133: JavaTM Memory Model and Thread Specification Revision
Synchronization and the Java Memory Model
Java Memory Model Pragmatics (transcript)
Memory Barriers: a Hardware View for Software Hackers
特别感谢感谢Jeremy Manson,帮助我纠正了很多误解,并为我更清楚地解释了那些对于我来说很新的术语。还要感谢Aleksey Shipilev,帮助我减少了本文草稿版本中出现的概念的复杂性。Aleksey还指导我们去他的JMM,语用学文章更深层次的理解,澄清和例子。
RHEL6.5安装OpenJDK1.7.0 + JBoss7.1.1 + Maven3.0.4
Fedora 20下安装官方JDK替换OpenJDK并配置环境变量
Ubuntu OpenJDK + Tomcat7 的安装
Ubuntu 13.04下升级到Maven3.10 以支持 OpenJDK7
关于作者Monica Beckwith是Java性能顾问。她过去曾经与Oracle/Sun和AMD一起工作,对JVM服务器级系统进行优化。Monica被评为JavaOne 2013的明星演讲者,并且是First Garbage Collector(G1 GC)性能团队的领导者。她的Twitter是@mon_beck。