The original semantics forvolatile
guaranteed only that reads and writes ofvolatile
fields would be made directly to main memory, instead of to registers or the local processor cache, and that actions on volatile variables on behalf of a thread are performed in the order that the thread requested. In other words, this means that the old memory model made promises only about the visibility of the variable being read or written, and no promises about the visibility of writes to other variables. While this was easier to implement efficiently, it turned out to be less useful than initially thought.
While reads and writes of volatile variables could not be reordered with reads and writes of other volatile variables, they could still be reordered with reads and writes of nonvolatile variables. InPart 1
, you learned how the code in Listing 1 was not sufficient (under the old memory model) to guarantee that the correct value forconfigOptions
and all the variables reachable indirectly throughconfigOptions
(such as the elements of theMap
) would be visible to thread B, because the initialization ofconfigOptions
could have been reordered with the initialization of the volatileinitialized
variable.
Unfortunately, this situation is a common use case for volatile -- using a volatile field as a "guard" to indicate that a set of shared variables had been initialized. The JSR 133 Expert Group decided that it would be more sensible for volatile reads and writes not to be reorderable with any other memory operations -- to support precisely this and other similar use cases. Under the new memory model, when thread A writes to a volatile variable V, and thread B reads from V, any variable values that were visible to A at the time that V was written are guaranteed now to be visible to B.
The result is a more useful semantics ofvolatile
, at the cost of a somewhat higher performance penalty for accessing volatile fields.
volatile的语义:
1. 确保对volatile域的读写操作都是直接在主存内进行,不缓存到线程的本地内存中。
2. 在旧的JMM中,volatile域的操作与nonvolatile域的操作之间可以重新排序。但是在JSR133以后,规定volatile操作和其他任何内存操作之间都不允许进行重新排序。
3. 在新的JMM下,当线程A写一个volatile变量V,然后线程B读取V的时侯,任何在写入V时对线程A可见的变量值,都对B可见
第3条很奇怪,感觉有点象synchronized的作用了。是不是线程A写入一个volatile变量时,会将自己的本地缓存中的non-volatile变量刷新到主存中,读一个volatile变量时会更新自己的本地缓存中的non-volatile变量?不然线程B又怎么能够看得见那些nonvolatile变量呢?
关于这个问题,查询了一些资料,有文章认为“volatile字段的读取和写入与进入和退出监视器具有相似的内存一致性效果”(http://blog.csdn.net/lovingprince/archive/2010/04/04/5450246.aspx
)
对于volatile变量的读写有一个happens-before的偏序关系
A write to a volatile fieldhappens-before
every subsequent read of that same volatile. 这点没有疑问。
Because the write of the volatile variableinitialized
happens after the initialization ofconfigOptions
, the use ofconfigOptions
happens after the read ofinitialized
, and the read ofinitialized
happens after the write toinitialized
, you can conclude that the initialization ofconfigOptions
by thread A happens before the use ofconfigOptions
by thread B. Therefore,configOptions
and the variables reachable through it will be visible to thread B.
在新JMM中使用volatile,可以确保上面的代码是合理的。以下"<"是happens-before的意思
1. “线程A中configOptions初始化” < “线程A中写initialized变量”
2.“线程B中读initialized变量” < “线程B中使用configOptions”
3. “write to volatile field” < “subsequent read of that same volatile”
并且有 action1 < action 2,action2 < action3,那么action1 < action3
所以我们可以得出:“线程A中configOptions初始化”< “线程B中使用configOptions”
也就是说,在使用了volatile变量后,使得non-volatile变量的操作之间也有了happens-before关系。
分享到:
相关推荐
5. ** Happens-Before 关系**:这是JMM中的一个重要概念,定义了两个操作之间的顺序关系,有助于理解和分析并发代码的执行行为。 6. **重排序规则**:JSR133规范了编译器和处理器可以进行的重排序类型,以保证正确...
2. **volatile增强**:JSR133增强了volatile关键字的功能,使其不仅提供了变量的可见性,还保证了单写多读操作的原子性。这使得volatile变量成为一种轻量级同步机制。 3. **synchronized优化**:规范对synchronized...
**JSR133中文版** 是一份关于Java内存模型(Java Memory Model,JMM)的重要文档,它详细解释了JSR(Java Specification Requests)133中的规范,该规范对Java平台的并发编程有着深远的影响。JSR是Java社区进程...
2. **volatile关键字的增强**:JSR133对volatile的语义进行了扩展,使其能够提供更强的同步保证,现在volatile写操作能立即刷新到所有线程的主内存中,而volatile读操作能立即从主内存获取最新值。 3. **final字段...
JSR133规范
在JSR-133中,对volatile变量的语义进行了强化,赋予了它们获取(acquire)和释放(release)的语义。在原来的规范中,volatile和非volatile变量的访问没有这样的区分。这一改变可能导致Java虚拟机监控工具(JVMTM)...
- **`volatile`的作用**:`volatile`关键字用于标记一个变量,以确保所有线程对该变量的读写操作都是立即可见的。这有助于实现轻量级的线程同步。 - **`volatile`的关键特性**:它禁止了编译器和处理器对带有此...
《JSR-133:JavaTM内存模型与线程规范》是Java多线程编程领域的重要指导文档,由JSR-133专家组制定,旨在解决Java平台中并发编程时可能出现的问题,确保多线程环境下的正确性和可预测性。这份规范与JavaTM平台Tiger...
JSR133中文版 .
JSR-133是Java Community Process(Java社区进程)中的一个规范,负责定义Java语言的内存模型和线程规范。该规范的主要目的是为了确保在多线程环境下,Java程序的执行结果是可预测和可靠的。 1. 锁 在Java中,锁是...
This document is the proposed final draft version of the JSR-133 specification, the Java Memory Model (JMM) and Thread Specification. This specification is intended to be part of the JSR-176 umbrella ...
JSR133-memory_model-1_0-pfd2-spec....读JSR133笔记 - 十年磨一剑 - ITeye博客.pdf The JSR-133 Cookbook.pdf jsr-133-faq.pdf JSR-133-Appr-The Java Memory Model.pdf 深入理解Java内存模型之系列篇 - CSDN博客.pdf
这使得volatile可以可靠地用于表示程序状态的改变,例如,标记一个状态变量已经初始化完毕,如清单1中的`initialized`变量。同时,volatile读写操作不再允许与非volatile变量的读写进行乱序重排,增强了内存操作的...
Java内存模型(Java Memory Model,简称JMM)是Java编程语言中的一个重要概念,它规定了程序中各种变量(线程共享变量)的访问规则,以及在并发环境中如何解决数据一致性问题。JMM的核心目标是为了确保所有线程能...
6. 多窗口支持:一个portlet可以同时在多个窗口中打开,提供并行交互体验。 7. 改进的安全性:增加了对portlet安全性的控制,如访问控制列表(ACLs)。 JSR168和JSR268的中文文档和开发手册对于理解和开发portlet...
- **volatile变量语义的加强**:在JSR-133之前,对volatile变量和非volatile变量的访问可以自由排序,但在新的规范中,volatile变量的操作具有了获取(acquire)和释放(release)语义,这意味着对volatile变量的...