Java programming explain high concurrency Series - No.13

Disclaimer: This article is a blogger original article, shall not be reproduced without the bloggers allowed. https://blog.csdn.net/nihui123/article/details/90702470

Before sharing, the class loading mechanism mentioned multi-threaded, said thread context class loader, also introduced memory usage on multi-thread, referred to a keyword volatile, introduction of the CPU cache mechanism introduced Java memory model.

Here's to introduce the three characteristics to be the most concurrent programming.

Three concurrent programming characteristics

Atomicity

  The so-called atomicity in the previous blog, or are referred to other information on the Internet. It refers to a process in operation or multiple operations, either all of the operations required to perform all, or is all of the whole operation is not performed. For example: In an account transfer operation performed when the step is to reduce the need for money account A and B account money increases. Then you need to perform this operation on both sides of success, money accounts can not appear to reduce the A and B accounts money has not increased, or that the money did not change the account A and B account money has changed.
  In fact, in the course of our programming operation, such as a simple assignment statement, if not guaranteed atomic operation, it would lead to erroneous data. But sometimes we encounter a situation that is two atomic operations together is not necessarily atomic. Volatile keyword in Java is not used to ensure atomicity, synchronized keyword can guarantee atomicity. Of course, starting from JDK1.5 offers a lot of variables to ensure atomicity. Atoms of these variables can guarantee atomicity operations.

Visibility

  Visibility between multiple threads means that when one thread to modify the shared variable, another thread can see the latest value immediately after the modification. In other words, we also mentioned in the previous example had on multi-threaded memory model, each thread operation when in fact, is the main variable in memory of the first copy in the cache, then the operation is complete after this variable back into main memory.

Orderliness

  Refers to the process of ordering the code execution is a sequential, during the period due to the Java compiler and runtime are optimized, resulting in the order of time and developers will actually write the real execution is not the same. E.g

int a = 10;
int b = 20;
a++;
b=0;

  The above code defines two variables a and b, and a variable of the increment operation of the variable assignment b. From the perspective of executing code written analysis also come from the usual flow analysis code, this code is executed from top to bottom. But the real running JVM process will not necessarily be in that order. This case is before the said instruction rearrangement (Instruction Recorder).
  In general such instructions rearrangement operation is performed on an optimized efficiency, of course, strictly abide by the instruction rearrangement of data dependencies between instructions, it is not free to be rearranged.
  Take those above procedure, the order of execution may be the case in the single-threaded code written, but there will be problems in the case of multi-threaded
example,

private boolean flag = false;
private Context context;

public Context load(){
	if(!flag){
		context = loadContext();
		flag = true;
	}
	return context;
}

  Above this come simulate the code from the Internet, that is to control whether the context is loaded over by flag, if there is a directive in the case of multi-threaded rearrangement, that is really load Context is lined up behind the flag = true , it will lead to the first thread after a normal load is complete, all the other threads will not be loaded.

JMM three characteristics guarantee

  In the above-mentioned three characteristics in the high concurrency, high concurrent programming of these three features are more important, so here's a look at a combination of Java memory model in Java through what kind of way to ensure that the three characteristic.

  Using a mechanism in the JVM memory model to differentiate between the various platforms to access memory, this can be considered to implement a memory access mechanism Java cross-platform, so Java programs on all platforms can achieve consistent access memory . The simplest example is not the same when the C language variables in memory on different platforms. But in Java on all platforms is four bytes.
  Also mentioned before all variables are defined JMM in main memory, each thread only its own local memory, threads for operating variables are in their working memory, main memory can not operate directly.

JMM and Atomicity

  In Java, the basic data type atomic read operation is for reading and reference types are atomic assignments. So is an atomic operation prosperity.

  1. Assignment variable a = 1;
    A = 1 operation is atomic, the thread will first perform a = 1 write working memory, and then write it to main memory. It may occur in the case of multi-threaded there is another thread to assignment of other values, but the end result can only be a 1 or other additional value. This is the variable assignment of atomicity
  2. Assignment between variables a = b;
    above this operation is a non-atomic operation, mainly comprising obtaining the value of b and assigning a value of b to the operation, these two operations obviously are separate in terms of atomic , but not together the atomic operations.
  3. Increment operator i ++;
    perform three-step process, the first step is to read the value of i from the main memory, and then into the working memory, a second step the value i in the working memory are incremented, the third step of the y values is written into main memory.

Integrated above three examples, that only the first operation is provided with atoms of the remaining operations of all the atoms in the informal. That

  1. Operation with a plurality of atomic operations is not atomic
  2. For simple read operations assignment is atomic, but if the value of a variable is not assigned to another atomic variables.
  3. JMM can only guarantee the basic read and atomic assignment, it does not guarantee atomicity other operations, if you want to guarantee the atomicity of other operations will need the synchronized keyword and lock operations.
JMM and visibility

  If a thread needs to acquire for the first time in a multithreaded environment following a shared variable, then you need to get the value of the variable start with main memory, and then enter into the working memory, perform the corresponding operation by operating the working memory variables. If you perform the modification of the operating variables, you need to first value is written into the working memory, then brush into the main memory, as to when this operation is uncertain. The following are three ways in Java to ensure visibility.

  1. Use the keyword volatile, when a variable is modified keyword, read operations to the shared resources will be (of course, this operation will be cached in the working memory directly in the main memory, when the other threads to shared resources has been modified, will lead to a shared resource for the current thread in the working memory fails, it must reacquire from main memory) for the write operation to the shared need to modify working memory, then brush into the main memory.
  2. By synchronized keyword to ensure visibility, synchronized keyword to ensure at the same time there is a thread to acquire the lock and then perform synchronization method, and working variables in memory will brush to main memory before the lock changed.
  3. lock provided by JUC can also guarantee visibility, Lock the lock method to ensure at the same time there will only be one thread to acquire the synchronization method, and ensure that the data in main memory after the operation is completed is the date.
JMM and ordering

  Java memory model, allowing the compiler and processor instructions rearrangement, also said that before the single-threaded case, no problem, but now is discussed multiple threads to run will lead to affect the results. Java provides three ways to ensure orderliness.

  1. Use the volatile keyword
  2. Use the synchronized keyword
  3. Use the Lock display

To ensure that the principles of orderliness and guarantee the visibility of the same. Of course, JMM there are a lot of native ordering rules, not allowed to be synchronized can be achieved, this rule is Happens-before principle. If the sequence of the two operations can not be performed from the push happens-before, it can not be guaranteed orderly.

to sum up

  By the example above we come to the conclusion corresponding to the three key features of the three.

volatile keyword does not have the guarantee atomicity semantics
The volatile keyword with guaranteed visibility semantics
volatile keyword with guaranteed sequential semantics.

Guess you like

Origin blog.csdn.net/nihui123/article/details/90702470