1. First-come, first-served threads
Let’s take a Dirty example: the bathroom in a restaurant is very small and can barely accommodate one person. In order to ensure that there is no interference, people who use the toilet must lock the door when entering the bathroom. We can think of the bathroom as a shared resource, and the many people who need to go to the bathroom can be regarded as multiple threads. If the bathroom is currently occupied, others must wait until the person finishes using the toilet and opens the door and comes out. This is just like when multiple threads share a resource, they must be prioritized on a first-come, first-served basis.
Someone said: What would happen if I didn’t have this door? Let two threads compete with each other. Whoever wins first can work first. How good is this? But we know that if the toilet does not have a door and people go to the toilet together, there will inevitably be disputes, the normal steps of using the toilet will be disrupted, and unexpected results are likely to occur. For example, some people You may have to apply fertilizer in the wrong place... It is precisely because of this door that anyone who enters the toilet alone can complete their toilet process smoothly without being blocked. Interference may even result in unexpected results. This means that when going to the toilet, you should be on a first-come, first-served basis.
So in a Java multi-threaded program, when multiple threads compete for the same resource, how can we ensure that they will not "fight"? Some people say that it uses a synchronization mechanism. That's right, the example above is a typical synchronization case. Once the first one starts going to the toilet, the second one must wait for the first one to finish before he can start his toileting process. Once a thread enters a certain process, it must wait for a normal return and exit the process before the next thread can start the process.
Here, the most critical thing is the bathroom door. In fact, the bathroom door plays the role of a resource lock. As long as the person going to the toilet locks the door, it is equivalent to obtaining the lock, and when he opens the lock and comes out, it is equivalent to releasing the lock.
In other words, the multi-threaded thread synchronization mechanism is actually controlled by the concept of locks. So how are locks reflected in Java programs?
Let us look at the concept of locks from the perspective of the JVM:
In the Java program runtime environment, the JVM needs to coordinate the data shared by the two types of threads:
1) Instance variables saved in the heap
2) Class variables saved in the method area
These two types of data are shared by all threads. (The program does not need to coordinate the data stored in the Java stack. Because these data are private to the thread that owns the stack.)
In the Java virtual machine, each object and class is logically Associated with a monitor.
For objects, the associated monitor protects the object's instance variables.
For classes, the monitor protects the class variables of the class. (If an object has no instance variables, or a class has no variables, the associated monitor monitors nothing.)
In order to realize the monitor’s exclusive monitoring capabilities, the Java virtual machine provides a All are associated with a lock. Represents a privilege that only one thread is allowed to have at any time. Threads do not require locks to access instance variables or class variables.
But if a thread acquires the lock, no other thread can acquire the same data lock before it releases the lock. (Locking an object is to obtain the monitor associated with the object)
Class locks are actually implemented using object locks. When the virtual machine loads a class file, it creates an instance of the java.lang.Class class. When an object is locked, what is actually locked is the Class object of that class.
A thread can lock the same object multiple times. For each object, the Java virtual machine maintains a lock counter. Every time the thread obtains the object, the counter is incremented by 1. Every time it is released, the counter is decremented by 1. When the counter value reaches 0, the lock is completely released.
Java programmers do not need to add locks themselves. Object locks are used internally by the Java virtual machine.
In a java program, you only need to use a synchronized block or a synchronized method to mark a monitoring area. Every time you enter a monitoring area, the Java virtual machine automatically locks the object or class.
The above is the detailed content of How to understand multi-thread synchronization in Java. For more information, please follow other related articles on the PHP Chinese website!