How Java volatile prevent instruction reordering

本文深入探讨了Java中volatile关键字的两大作用:确保变量可见性和禁止指令重排序。通过实例解析了volatile如何解决多线程环境下变量同步的问题,并讨论了使用volatile进行双重检查锁定时需要注意的细节。

Two roles voliate keywords

1, to ensure the visibility of variables: when a modified volatile keyword variable is modified when a thread, other threads can instantly get the results after revision. When a thread writes data to be modified volatile keyword variables, the virtual force it to be flushed to main memory value. When a thread uses modified volatile keyword value, the virtual machine it is mandatory to read from main memory.
2, reordering mask instruction: instruction reordering is correct compiler and processor in order to efficiently optimize the program means, which can ensure that the results of program execution, there is no guarantee sequential program operation coincides with the order of the code. This is not a problem in a single thread, but the problem will appear in multiple threads. Very classic example is voliate added simultaneously in a single field in the Example, it is to prevent the reordering of instructions.

Compile reordered sequence of instructions typically is adjusted, so that without changing the semantics of the program premise, to minimize the read register number is stored, to fully reuse the stored value of the register.
For example, we have the following code:


 
  1. int x = 10;

  2. int y = 9;

  3. x = x+10;

Assuming that the compiler directly on the above code is compiled, without reordering, we simply analyze the execution of this code, first load the memory address of the variable x to the address register, and then loaded 10 into the data register, then the CPU mov the instruction address register 10 is written into the specified memory address. Then load the memory address of the variable y in the address register, the data is loaded into the register 9, 9 is written to the memory address. When the third row of the implementation, we found that the CPU needs to reload x memory addresses and data to register, but if I put the third row and the second row a change order, then the implementation process to access the register can be a lot less times, while no effect on the results of the proceedings.

Another example can be configured to look at the code lock check double single embodiment below


 
  1. public class Singleton {

  2. private volatile static Singleton singleton;

  3.  
  4. private Singleton() {}

  5.  
  6. public static Singleton getInstance() {

  7. if (singleton == null) { // 1

  8. sychronized(Singleton.class) {

  9. if (singleton == null) {

  10. singleton = new Singleton(); // 2

  11. }

  12. }

  13. }

  14. return singleton;

  15. }

  16. }

In fact, when the program is executed at the time 2, if we do not modify variables singleton using the volatile keyword, it may cause an error. This is because the new operator initializes an object of the process is not an atomic operation, it is divided into the following three steps:

  1. To allocate memory singleton
  2. Call to Singleton's constructor to initialize member variables
  3. The singleton object points allocated memory space (End perform this step on a non-null the singleton)

If the virtual machine instruction is present reordering optimization, the order of steps 2 and 3 can not be determined. If thread A and the first to enter the first synchronized block 3 is performed without performing 2, already at this time because the non-singleton null. This time the thread B to 1, and determined non-null return singleton used, because the fact has not been initiated Singleton, naturally wrong. sychronized can solve the visibility of memory, but can not solve the problem of reordering.

But pay special attention to the use of volatile double check the lock is still a problem in the previous version 1.5 jdk. The reason is that Java 5 former JMM (Java Memory Model) is flawed, real-time variable declared volatile reordering can not be completely avoided, mainly the code before and after volatile variable reordering problem still exists. The volatile question was able to shield the reordered in jdk 1.5 (JSR-133) repair, this time to the volatile jdk enhanced semantic, objects are added to the volatile read-write memory barrier, in order to ensure visibility at this time 2 -3 becomes the code sequence without being rearranged CPU, so after that we can rest assured that use volatile.

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值