High Concurrency Essentials (2)-Why are threads unsafe?

In the case we mentioned in the last issue, the three window thread selling tickets have the same problem as the window selling tickets, that is, the "thread insecurity problem". In this article, we will talk about "why thread does not appear. Safety".

 

1. What is thread safety?

 

Thread safety was first defined by Brian Goetz in the "Java Concurrency In Practice" (Java Concurrency In Practice) written by him. It is defined as follows:

 

When multiple threads access an object, if you do not need to consider the scheduling and alternate execution of these threads in the runtime environment, and do not require additional synchronization, or do not perform other coordination operations in the caller's code, the behavior of this object is obtained The result is still correct, the one calling this object thread safe.

 

In our previous three-thread ticket selling case, multiple threads access the ticket data of the same object, but we found that the data obtained by operating this object sometimes has repetitive wrong results, so we said that we wrote before selling The ticket case is "thread unsafe".

 

Although we know that the phenomenon of repeated data access by three threads accessing the ticket is thread-unsafe, but I don't know why it is not safe to access data concurrently by multiple threads, so next we will talk about "why thread concurrent access is not safe".

 

2. The stateful and statelessness of the object

 

In Java, objects can be divided into stateful and stateless according to their state .

 

Stateless Bean: A stateless object is an object without instance variables, so it cannot save data. It does not contain domains and does not reference domains of other classes. And because the stateless object has no stored data, the object has nothing to change, so it is immutable. Any operation on the object under the same multithreading will not change the state of the object. So "a stateless object must be thread-safe". The stateless case is defined as follows:

 

 

Stateful Bean: It is an object with instance variables that can store data.

 

We know that the data of the instance is stored in the heap, and the data in the heap can be shared by multiple threads (as shown above).

 

When multiple threads access data in the same heap at the same time for read and write operations, the race condition is reached, and the final result when multiple threads compete for resources to read and write data will not be as correct as we expected, and thread-unsafe Happening. At the same time, the state of the data object of the modified object is also changed, so it is called a stateful object. The definition case is as follows:

 

 

3. Race conditions

 

Race conditions are caused by incorrect results due to improper execution timing when an object or an unsynchronized shared state is modified by multiple threads. Analyze our previous ticket selling case:

 

 

If you are accessing the shareable object MyRunnable at this time, if the two threads "Window 1" and "Window 2" enter the run method at the same time and execute to the code in the figure. The timeline of code executed under competition may be as follows:

 

 

It can be seen from the figure that when the "window 1" thread gets the ticket data and judges that ticket>0, the ticket is 100 at this time, and the "window 2" thread is outputting the ticket result at this time and it is still 100, and then After the "window 1" thread outputs 100, the ticket-- operation is executed.

 

Therefore, the result of the two threads starting to output the value of the ticket is 100; we found that the data accessed by multiple threads under race conditions is "dirty data", that is, wrong data.

 

4. Order rearrangement and order


In fact, in addition to improper execution timing during race conditions, instruction rearrangement will also cause the order of code execution to not be executed according to your written order.


The general steps of code operation are as follows:
1. Get instruction decoding from main memory
2. Calculate value in thread memory
3. Perform code operation
4. Write result into main memory (main memory is shared by all threads)

and write result The operation of the main memory is time-consuming. In order to improve performance, the CPU may not wait for it to complete before proceeding to decode the next instruction. This is the instruction rearrangement. The definition is as follows:
Instruction rearrangement: The computer reorders the assembly instructions for performance optimization in order to make full use of the processing performance of the hardware.

 

Classic Case:

 

 

Analysis: Although the order of our code writing is "Step 1", "Step 2", and "Step 3", the CPU will execute the code according to the optimal performance and ensure that the final result remains unchanged during processing. That is to say, the last step is "step 3" to perform the "a+b" operation, but the order of "step 1" and "step 2" may be the first three:

 

(1) "Step 1" precedes "Step 2"

(2) "Step 1" and "Step 2" are executed in the same time slice

(3) "Step 1" is executed after "Step 2"

 

Instruction rearrangement will change the order of code execution, but because the final execution result remains the same, there is no problem in a single thread.

 

And if in multiple threads, one data is operated at the same time, if one reads and one writes, when the value of the writing thread has changed but has not been written to the main memory (that is, the value change has not been seen by other threads), Another thread has already started to read, then there will be inconsistent results at this time.

 

In fact, it is now very clear why multi-threaded concurrency is insecure. The fundamental reason is that multi-threading is not shared, and it is impossible to accurately know the state of each other, including the modification of values. Will cause problems to modify the data, and thread insecurity.

 

The above introduces a main memory shared by all threads, so what is the main memory? What is the memory model of thread operation? Don't worry, we will introduce the thread model and the memory model of java thread in the next part.

 

 

Guess you like

Origin blog.csdn.net/weixin_43802541/article/details/112968884