In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-11 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >
Share
Shulou(Shulou.com)06/02 Report--
This article is to share with you what are the sources of concurrent bugs, Xiaobian thinks it is quite practical, so share it with you to learn, I hope you can gain something after reading this article, not much to say, follow Xiaobian to have a look.
visibility
Changes made by one thread to a shared variable that another thread can immediately see, we call visibility
When it comes to visibility, we must first introduce the concept of JMM (Java Memory Model), that is, Java memory model, Java memory model stipulates that all variables are stored in the main memory, when the thread uses variables, it will copy the variables in the main memory to its own workspace or private memory, and when the thread reads and writes variables, it operates on variables in its own working memory.
Using Git workflow to understand the above description is very simple, Git remote repository is the main memory, Git local repository is its own working memory
The text description is somewhat abstract, let's illustrate it:
Look at this scene:
There is a variable x in main memory with an initial value of 0.
Thread A adds 1 to x by copying x=0 into its own private memory and updating the value of x.
Thread A flushes the updated x value back into main memory at variable times.
Just when thread A does not flush x back into main memory, thread B also reads x from main memory, which is 0 in this case. The same operation as thread A, the last expected x=2 will program x=1.
This is the problem of thread visibility
JMM is an abstract concept. In practice, the working memory of a thread looks like this:
In order to balance the memory/IO board, cache will be added to the CPU, each core has only its own level 1 cache, and even a level 2 cache shared by all CPUs, which is the image above. It is said that this design is a pit left by hardware students to software students, but whether you can jump over this pit is also a key indicator to measure whether software students are moving towards Java advancement...
tips
As you can see from the above figure, in Java, all instance fields, static fields, and array elements are stored in heap memory. There are shared variables between threads in the heap. These are called "shared variables" in subsequent articles. Local variables, method definition parameters, and exception handler parameters are not shared between threads, so they do not have memory visibility problems and are not affected by the memory model.
In short, to solve the multithreaded visibility problem, all threads must flush variables from main memory. How do you solve the visibility problem? Java keyword volatile to help you out, the following chapters will analyze...
atomicity
Atom refers to the elementary particle that cannot be divided into chemical reactions. You should be able to feel the meaning of atomic operation:
Atomic operations are operations that are not interrupted by thread scheduling mechanisms; once started, they run to the end without any context switch in between
There is a very classic line in the sketch "hourly worker". How many steps do you have to take to install the elephant in the refrigerator?
Let's look at a short program:
Can we expect count = 20000 in multithreading? Some students may think that the counter method called by the thread has only one count++ operation, which is a single operation, so it is atomic, not also. In the thread first lecture said that we can not use high-level language thinking to understand the CPU processing mode, count++ conversion to CPU instructions requires three steps, through the following command to parse out assembly instructions and other information:
javap -c UnsafeCounter
The counter method is called the counter method.
16 : Get the current count value and put it at the top of the stack 19 : Put constant 1 at the top of the stack 20 : Add the two values at the top of the stack and put the result at the top of the stack 21 : Assign the result at the top of the stack to count
It can be seen that the simple count++ is not a one-step operation. After being converted to compilation, it does not have atomicity. It is like an elephant installing a refrigerator. In fact, it has to be divided into three steps:
Step one, open the refrigerator door; step two, put the elephant in; step three, close the refrigerator door
Combined with JMM structure diagram understanding, explain why it is difficult to get the result of count=20000:
Multithreaded counters, how to guarantee atomicity of multiple operations? The crudest way is to add synchronized keywords to methods, such as:
The problem is solved, if synchronized is a panacea, then maybe concurrency is not so much, you can rely on a synchronized world, the fact is not the case, synchronized is an exclusive lock (only one thread can be called at the same time), threads that do not acquire the lock will be blocked; in addition, it will bring a lot of thread switching context overhead.
So JDK has a non-blocking CAS (Compare and Swap) algorithm to achieve atomic operation class AtomicLong and other tool classes, read the source students may find a common feature, all atomic classes have the following code:
private static final Unsafe unsafe = Unsafe.getUnsafe();
This class is JDK's rt.jar package Unsafe class provides hardware-level atomic operations, the methods in the class are native modified, and several methods in this class will be explained before introducing atomic classes later. Here is a brief introduction to an impression.
Some students do not understand what I just mentioned thread context switch overhead means, give two examples you understand:
You (CPU) are reading two books (two threads). After reading the first book for a short time, you have to read the second book. After reading the second book for a short time, you have to read the first book again. And you have to remember exactly what line you saw. What did you see at the beginning (CPU remembers thread level information)? When you read 10 books or more at the same time, the switching cost is very high.
There are a lot of games in variety shows that let you count money while doing other things, and finally ensure that all kinds of things are done correctly. The brain overhead is not big. You will know when you try.
orderliness
Ask someone in your life,"Did you eat?" And "Have you eaten?" It means that you wrote the following program:
a = 1;b = 2;System.out.println(a);System.out.println(b);
The compiler optimization might look like this:
b = 2;a = 1;System.out.println(a);System.out.println(b);
In this case, the compiler adjusted the statement order without any effect, but the compiler optimized the order without authorization, and it buried a mine for us, such as a single case implemented by double checking.
Everything is perfect again, yes, no, the problem arises in instance = new Singleton();, this 1 line of code is converted into CPU instructions and becomes 3, we understand that the new object should be like this:
Allocate a block of memory M
Initialize Singleton object on memory M
Then the address of M is assigned to the instance variable
However, the compiler may become like this after unauthorized optimization:
Allocate a block of memory M
Then assign the address of M to the instance variable
Initialize Singleton object on memory M
First of all, the new object is divided into three steps, leaving the CPU with the opportunity to switch threads; in addition, the order optimized by the compiler may lead to problems, see:
Thread A executes getInstance method first, and when it executes instruction 2, thread switch happens
Thread B has just entered the getInstance method and determines whether the if statement instance is empty.
Thread A has assigned the address of M to instance, so Thread B assumes instance is not empty.
Thread B returns instance directly
CPU switches back to thread A, thread A completes subsequent initialization
Let's draw a picture to illustrate:
If thread A executes to step 2, thread switch, because thread A does not execute the red arrow completely, thread B will get an uninitialized object, NPE may occur when accessing instance member variables, if the variable instance is modified with volatile or final (involving the class loading mechanism, see my previous article: parental delegation model: factory high frequency interview questions, easy to handle), the problem is solved.
summary
The program you see is not necessarily a compiler optimized/compiled CPU instruction. Elephant refrigerator is a program, but it implies three steps. Learning concurrent programming, you have to consider the problem according to CPU thinking, so you need to deeply understand visibility/atomicity/orderliness. This is the source of concurrent bugs.
This section describes three problems, the following articles will also analyze the solutions to the above problems one by one, as well as relatively good solutions, please continue to pay attention, in addition to the concurrent test code I will upload to github by example, public number reply "demo"--> concurrency Get more content
soul inquiry
Why is a variable decorated with final thread-safe?
Do you often check CPU assembly instructions?
If you were asked to write a single example, what kind of implementation would you typically use?
Efficiency tools
Material Theme UI
This is an IDEA theme plug-in, after installation, select the Material Palenight theme, and make the following settings
After setting up, your IDEA is like this, causing extreme comfort. What are the sources of concurrent bugs? Xiaobian believes that some knowledge points may be seen or used in our daily work. I hope you can learn more from this article. For more details, please follow the industry information channel.
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.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.