Java Concurrency (a) Concurrency Features

Recent would like to summarize some of the Java concurrency-related content, to write it, where what is written [Behind his]

1, concurrency issues physical computer

Before explaining the Java concurrency features, briefly look at concurrency problems in the physical computer, both of which have many similarities. Physical machine concurrent treatment options for virtual machines is also a great reference value.

"Concurrency" in the computer field, has been a headache. Concurrent computing is not just because things do, is stored. When we deal with concurrency, can not rely on CPU can be done, it needs to interact with memory, such as data read operation, store calculation results.

However, since the processing efficiency and the processing efficiency of the CPU memory of several orders of magnitude difference, the computer had to introduce a cache as a buffer between the memory and the CPU, data copying operation will require the use of the cache, reducing the I / O bottleneck, acceleration operation, when the operation is completed, then the data from the cache memory back into synchronization, this can improve the efficiency of many processes.

However, while introducing the cache, it also brings another problem - cache coherency. Each processor has its own cache, but they share the same main memory when multiple processor tasks are related to the same piece of main memory area, there will be inconsistencies in the data cache issue.

Meanwhile, in order to solve the problem of consistency, we need to follow some cache coherency protocol (MSI-peer protocol) to regulate read and write data.

Specifically schematic, as follows:

figure 1

Note: The introduction of the concept of concurrent physical computer, primarily to provide an idea, in fact, to achieve more complex than described.

2, Java memory model

As we all know, running Java itself is based on a virtual machine, the virtual machine specification, defines a Java memory model, to block out the memory access hardware and operating system differences, in order to achieve let Java programs in a variety of platforms memory access can achieve the same effect.

Model divided into the main memory and working memory, all variables (except for local variables, local variables are thread private, there is no concurrency issues) are stored in main memory. Each thread has its own working memory, working memory which holds a copy of a copy of main memory to use thread variables, thread all operations on variables (reading, assignments, etc.) must be in working memory, while not directly operation of the main variables in memory. Between different threads can not access each other's working memory, variable value passed between threads are required to complete the main memory, the diagram is as follows:

figure 2

Note: This mention of main memory and working memory, and in fact, we often say that the memory is divided into Java heap, stack, and other methods zone is not the same level of the division, both basically no direct connection. If we must reluctantly correspond, then the main memory corresponds to the main part of the Java heap object instance, while working memory corresponds to the portion of the area of ​​the virtual machine stack. From the lower level, said main memory corresponding to the physical hardware direct memory, working memory may be preferentially stored in the cache.

About concrete between main memory and the working memory of the interactive protocol, that is, how a variable copy from main memory into the working memory, but also how to synchronize back to the main memory from the working memory. Java defines eight modes of operation to be achieved, and the virtual machine to ensure that each operation is atomic.

Note: 8 kinds of operations are lock, unlock, read, load, use, assign, store, write.

image 3

As shown in the figure, two sets of operation, a set of read, one group is written.

It is noteworthy that, Java model requires only two operations must be executed sequentially, but not guaranteed to be performed continuously, this difference is very large.

That is, between the Load and the read, write and store between other instructions can be inserted.

Next, we look at three features of Java Concurrency in, atomicity, visibility and order

Atomicity

By the Java memory model, we can see that at work memory and main memory interaction, although each instruction is atomic, but each set of instructions is not sequential.

For example, when we order the main memory variables a, b access, a possible scenario is

read a、read b、load b、load a.

Therefore, in a multithreaded environment, the problems of concurrent access to the main memory data will appear.

So Java is how to meet the needs of atomicity of it?

Java memory model is provided to lock and unlock operation needs atomic.

Despite the virtual machine does not operate directly to users, but provides a higher level of grammar, which is synchronized block --synchronized Java code.

Of course, the use of atomic ReentrantLock also meet.

Note:

The basis of the type of a variable (byte, short, int, float, boolean, etc.) are atomic operations, there is no concurrency issues, decompile into assembly language, you can see the operation of only one type of a variable basis assembler statements.

However, for long and dobule type atomic operation may not be the main reason is because these two are 8-byte (64-bit), Java specification allows read and write operations to divide 64-bit data into two 32-bit operating.

Visibility

Visibility means that when a thread changes the value of shared variables, other threads can be aware of this change immediately. Java memory model by modifying the value of the variable after the new sync back to main memory, the main memory refresh value from the variable before the variable read. This embodiment relies main memory as a transfer medium to achieve visibility.

For ordinary variables,, Java is not guaranteed visibility, as shown below:

Figure 4

Thread 1 and Thread 2 x will be read into the working memory, but the thread 2 the value of x was changed to B, and no update main memory, a working memory at this time remains the value a. That there is the issue of visibility.

Java is achieved using the volatile keyword visibility of variables.

volatile variable, after the modified value will be immediately flushed to main memory. And before each use are flushed from the main memory.

Note: synchronized but also to achieve visibility

Orderliness

In order to improve efficiency, make full use of computing power, real-time compilers will command the Java virtual machine optimized reorder.

Reordering instructions, the order does not guarantee the same code program in the order of execution of the individual statements, but it will ensure that the results of the final result of the execution of the program and the results of the code sequence is the same.


//同一个线程内

int a=10;//语句1

int r = 2;//语句2

a = a+3;//语句3

r= a*a;//语句4

复制代码

The order of execution might look like this:

Figure 5

That there is no possibility statements and statements 4 3 A change?

This is not possible because the statement 4 3 depends on the statement, the statement can only be performed after the statement 4 3.

These are single-threaded case, a single thread, while instructions may be chaotic, but the results of the final execution is ordered.

That, for the case of multiple threads, is not the same, we look at an example.

//线程1

context = loadContext(); //语句1

inited = true; // 语句2

//线程2

while(!inited) {

    sleep();

}

doSomething(context);
复制代码

Example, the statement and thread 1 1 2 no dependencies, so reordering may occur.

If reordering occurs, thread 1 executes the process of implementation of the first two, but this time the thread 2 that the initialization has been completed, it will be out of the loop, execution doSomething (context) method, but this time did not initialize context, will lead to program error.

This is complicated by the problem of disorder can cause.

Java provides a mechanism to ensure orderliness, by volatile and synchronized can be achieved.

We will look at the transformation of the above code:

//线程1

context = loadContext(); //语句1

volatile inited = true; // 语句2

//线程2

while(!inited) {

    sleep();

}

doSomething(context);
复制代码

In this case, the order of sentence 2 and sentence 1 will be guaranteed.

In this paper, reference

"In-depth understanding of the Java Virtual Machine Second Edition" Zhou Zhiming

Guess you like

Origin juejin.im/post/5d04e0f451882570da220368