Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

JVM memory model, visibility, instruction reordering

2025-02-24 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

Shulou(Shulou.com)06/02 Report--

This article focuses on "JVM memory model, visibility, instruction reordering", interested friends may wish to take a look. The method introduced in this paper is simple, fast and practical. Let's let the editor take you to learn "JVM memory model, visibility, instruction reordering"!

Memory model

First of all, let's think about what one java thread should do to communicate with another thread, and let's be clear about the requirements. How can a java thread notify another thread of an update to a variable? We know that instance objects and array elements in java are placed in the java heap, and the java heap is shared by threads. (here we call the java heap main memory), and each thread is its own private memory space (called working memory). If thread 1 wants to communicate with thread 2, it must go through a similar process:

1. Thread 1 updates the X in its working memory to 1 and flushes it to the main memory

2. Thread 2 reads the variable Xroom1 from main memory and updates it to its own working memory, so that the X read by thread 2 is the updated value of thread 1.

From the above process, we can see that the communication between threads needs to pass through the main memory, while the interaction between the main memory and the working memory needs to be managed by the Java memory Model (JMM). The following figure shows how JMM manages main and working memory:

When thread 1 needs to refresh the value of an updated variable to main memory, it takes two steps:

1. Perform store operations in working memory

2. Perform write operation in main memory

After completing these two steps, the variable values in the working memory can be refreshed to the main memory, that is, the variable values of thread 1 working memory and the main memory are the same.

When thread 2 needs to read the latest value of a variable from main memory, it also goes through two steps:

1. The main memory performs the read operation to read the variable value from the main memory.

2. The working memory performs the load operation to update the read variable value to the copy of the local memory.

After completing these two steps, the variable values of thread 2 are consistent with those of the main memory.

Visibility

There is a keyword volatile in Java. What is the use of it? In fact, this answer is in the above java inter-thread communication mechanism. Let's imagine that thread 1 and thread 2 must have the problem of delay due to the emergence of working memory as an intermediate tier. For example, thread 1 updates variables in working memory, but it is not refreshed to main memory. At this time, thread 2 obtains the value of variables that have not been updated, or thread 1 successfully updates variables to main memory. But thread 2 still uses the value of the variable in its own working memory, which will also cause problems. No matter which situation occurs, it may cause the communication between threads not to achieve the desired purpose. Examples include the following:

/ / Thread 1 boolean stop = false; while (! stop) {doSomething ();} / Thread 2

Stop

= true

This classic example shows that thread 2 controls thread 1 to interrupt by modifying the value of stop, but unexpected results may occur in the real world. Thread 1 does not interrupt immediately or even all the time after thread 2 executes. The reason for this is that thread 2 cannot get the variable update of thread 1 the first time.

But when Volatile came along, it was no longer a problem. Volatile promised two things:

1. Update of variables in thread 1 working memory forces writing to main memory immediately

2. Variables in thread 2's working memory will be forced to invalidate immediately, which makes thread 2 have to go to the main memory to get the latest variable value.

So it is understood that Volatile ensures the visibility of variables, because thread 1's modifications to variables make thread 2 visible the first time.

Instruction reordering

Let's take a look at a piece of code about instruction sorting:

Int a = 0; 
 boolean flag = false

/ / Thread 1

Public void writer () {

A = 1

Flag = true

}

/ / Thread 2

Public void reader () {

If (flag) {

Int I = axi1

. }

}

Thread 1 executes axiom 1 in turn; after thread 2 judges flag==true, set i=a+1. According to the code semantics, we may infer that the value of I is equal to 2 at this time, because thread 1 has already executed axiom 1 when thread 2 judges flag==true. Therefore, the value of I is equal to aquifer 1, but this is not necessarily the case. The cause of this problem is that two statements within thread 1, a1bot truth, may be reordered, as shown in the figure:

This is a simple demonstration of instruction reordering, in which two assignment statements, although their code order is one before and after the other, are not necessarily executed in code order. You might say, isn't that a mess with this command to reorder? The programs I write do not follow my code flow, how to play this? You can rest assured that your program will not be messed up, because there are strict instruction reordering rules between java, CPU and memory, and there are rules for what can and cannot be rearranged. The following process demonstrates what reordering a java program undergoes from compilation to execution:

The first step in this process is compiler reordering, which is strictly carried out according to the JMM specification. In other words, compiler reordering generally does not affect the correct logic of the program. The second and third steps belong to processor reordering, so processor reordering JMM is not easy to manage. What should I do? It requires the java compiler to add a memory barrier when generating instructions. What is the memory barrier? You can think of it as an airtight shield that protects java instructions that cannot be reordered so that the processor will not reorder them when it encounters a memory barrier protection instruction. About where to add the memory barrier, what are the types of memory barrier, what is the role of each, these knowledge points will not be elaborated here. You can refer to the relevant materials of JVM specification.

Here is the logic that will not be reordered in the same thread:

In these three cases, the result of arbitrarily changing the order of a code will be very different, and for such logical code, it will not be reordered. Note that this means that it will not be reordered in a single thread, but logic problems will still arise in a multithreaded environment, such as the example we gave at the beginning.

At this point, I believe you have a deeper understanding of "JVM memory model, visibility, instruction reordering". You might as well do it in practice. Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Internet Technology

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report