Is volatile enough to ensure data synchronization?

Source: Internet
Author: User

I have learned about the Java Memory Model in the previous section. To improve the execution performance, jmm introduces two concepts: working memory and primary memory. before continuing to discuss this, we must first clarify four storage media types: registers, advanced caches, ram, and Rom.

Ram and Rom are familiar to everyone. We can think of them as memory and hard disk. Registers are part of the processor, the advanced cache is a cache introduced by the CPU designer to improve performance. It can also be said to be part of the processor. When the CPU is used for computation, it must involve reading the operands. If the CPU reads the ROM directly, the read speed is simply intolerable. Therefore, the Memory RAM is introduced, this has indeed increased the speed. However, due to the rapid development of CPU and the slow development of Ram due to technical and cost restrictions, a difficult conflict arises, the CPU operation speed is several orders of magnitude faster than reading data from Ram. We are familiar with the barrel principle. The capacity of the bucket depends on the shortest block, which will inevitably affect the efficiency of the processor, as a result, the advanced cache is introduced, and several levels of cache are directly added to the CPU. Although their speed cannot be compared with the Register, the speed has increased a lot, it basically matches the computing speed of the CPU. To solve the conflict between the CPU operation speed and the read speed, a multi-level storage mechanism is introduced.

As shown in Figure 2-5-2-1, the four storage media of the machine are related. Generally, the Rom-related program data is read into RAM when the program is running, the data to be computed or the data to be used in the operation process will be read into the cache or register, if all the data and commands required for the operation are in registers and high-speed cache, the operation process is very flat and has no performance bottleneck, because the calculation speed basically matches the read speed. The reading speed is sorted as follows: Register> cache> Ram> Rom, which is interpreted by a concept that is easy to understand but not completely correct, because the registers are closest to the CPU, therefore, read speed is the fastest, cache speed is the second, Ram is the third, Rom is the farthest, and the natural speed is the slowest (of course, distance cannot be fully used to illustrate this problem, but distance is a better understanding, in addition, these storage media have different hardware designs and work methods ). From another point of view, the CPU reads data in the order of first try reading the register. If not, try to read the cache. If not, read the ram and read the Rom. Some CPUs have three-level cache, which is read from the first-level cache until the required operands are found. Generally, a better CPU Level 3 cache can make the hit rate reach more than 95%.

Figure 2-5-2-1 four storage media

 

With the above knowledge, further exploration will be successful. If we compare the Java memory model with the multi-level storage mechanism, we will find that Java introduces the concept of working memory to improve performance, this improves the speed at which data is read during thread execution. In this way, the main memory and working memory in the Java model can be mapped to Ram and high-speed cache or register, respectively, the working memory of each thread copies the required data to the high-speed cache or register (but it is not guaranteed that all the variable copies in the working memory are stored in the high-speed cache, or in Ram, specifically, it depends on how the JVM is implemented. In this way, the performance is guaranteed when multiple threads are concurrent. Of course, there is a capacity limit for registers and high-speed cache due to cost, which is also a challenge to test JVM implementation.

A mechanism is introduced to solve one problem, but it also brings about another problem. Data Synchronization is another problem, that is, whether the variable values used by the current operation are always the latest values at the current time. If the variable value is not the latest value, it will lead to dirty data reading, which may lead to different calculation results. At this time, someone may think of a volatile keyword in Java. There is no doubt that it can ensure visibility, so that every thread obtains the latest variable value in the main memory, but is it enough to ensure data synchronization? For example, the pseudocode is as follows:

Private volatile int COUNT = 0;

Private void increase () {count ++}

Public static void main (string ARGs ){

Create 30 threads for execution;

Each thread task executes the increase () method 10000 times;

}

After all the thread tasks are executed, we expect the result to be 30*10000, but it is actually a number smaller than 30*10000. It must have been a bit strange at first, but after careful consideration, it is clear that after count ++ is compiled, it is not an atomic operation. It is implemented by combining several commands. Figure 2-2-2 clearly shows this point. In the Java memory model, Count ++ is divided into five steps (of course, this is not the exact command execution step ), these five steps are not Atomic. If other threads read the Count variable of the primary database during the completion process, it obviously leads to dirty reading.

Figure 2-5-2-2

The reason for this problem is that volatile does not have a lock operation. It is not difficult to solve this problem, that is, to change these five steps into atomic operations, that is to say, before the thread completes, no other thread can read the Count variable, and a mutex lock can be applied to the Count variable. Thread 1 locks the Count variable before executing step 1, other threads cannot access count. After the thread executes step 5, it releases the lock. At this moment, other threads are allowed to obtain this variable.

Volatile is a keyword that is easy to mix up. Many experienced developers cannot use it correctly. This section describes the corresponding Java memory model from the machine structure, the problem of data synchronization between the master memory and the working memory is further introduced, which better explains the exact meaning of volatile-it only guarantees visibility, and it is not enough to ensure data synchronization.

Is volatile enough to ensure data synchronization?

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.