Volatile, the lightest synchronization mechanism
1. The Volatile is introduced
Volatile: Ensures that operations on this variable are visible to different threads. When one thread changes the value of a variable, the new value is immediately visible to other threads.
Without volatile, one thread changes a variable, and other threads do not necessarily know that the variable has been changed. When a thread changes the value of a member variable, it is not certain when the data of the member variable in main memory will be changed, so other threads will not know when the value is changed.
For better understanding, here is the JMM (Java Memory Model) : each thread has its own working memory, and each thread can only operate in its own working memory. It cannot change the contents of the working memory in other threads, nor can it change the contents of data in the main memory.
2. The shortage of the Volatile
It can only guarantee visibility of data, but not atomicity of operations or thread-safety.
3. Conceptual supplement
- Visibility: Changes made to a variable in one thread will directly modify the data in main memory and cause the backup data of other threads to be marked as unavailable. Other threads will retrieve the data in main memory if they use the changed data.
- Atomicity: A piece of code (a series of instructions) that is either not executed or executed all at once without the execution of other instructions.
- Thread-safe: While one thread is writing or modifying data, other threads cannot modify the data.
Synchronized built-in lock
1. Introduction
The keyword synchronized can be used to modify methods or in the form of synchronized blocks. It mainly ensures that multiple threads can only have one thread in a method or synchronized block at the same time. It ensures the visibility and exclusivity of thread access to variables, also known as the built-in lock mechanism.
2. Object locks and class locks
In fact, both object locks and class locks are objects of locks, except that the object lock locks the object instance, and the class lock locks the.class object.
- Object lock: Locks specific objects. Example: non-static methods with the synchronized keyword. Synchronized () in the block, with the concrete object in parentheses.
- Class lock: Locks. Class objects. Example: static method with synchronized keyword. Synchronized () in the block, with the specific ****. Class in parentheses
Concept:
1. There can be many instances of a class object, but only one.
2. Class objects can only be created by the JVM, are created when the.class object is loaded, and are created only once.
Principle 3.
- Synchronized is simply an object lock, and the state of the lock is stored in the head of the object of the lock.
-
So synchrozied has three lock states: bias lock, lightweight lock, and heavyweight lock
-
Biased lock: When a thread accesses a locked method, the object header is changed to biased lock. Subsequent access is based on the ID of the thread to determine whether it is the previous thread. If it is, it is directly entered. Otherwise, STW (Stop the world) waits for the previous thread to complete and changes the object header to a lightweight lock.
-
Lightweight lock: the logic +CAS of circular lock is used. When the lock competition is not fierce, the CAS method can reduce the thread context switch and improve the performance.
-
Adaptive spin locks (Synchrozined optimization) : Upgrade to heavyweight locks when the spin time exceeds the context switch.
-
Heavyweight lock: The thread that did not acquire the lock enters the blocking queue, and the thread is blocked.
4. Error-prone locking cases
We can see from the decomcompiled bytecode that the i++ operation is integer.valueof (), and that the last operation is integer.valueof () :
So once I ++ is done, the I object is not the same object when each thread enters the synchronized code block.
Third, ThreadLocal
1. Introduction
ThreadLocal provides each thread with a copy of a variable so that each thread is not accessing the same object at any one time, thus isolating multiple threads from sharing data.
Principle 2.
- Gets the ThreadlLocalMap object in the current thread object based on the current thread.
2. Then use the ThreadlLocalMap with ThdreadLocal as the key and ThreadLocal as the Value. Get, store data.
3. Problems and defects in use
-
Either override the initialValue method when initializing ThreadLocal, innovating the initial object.
-
When a thread drops the set method of ThreadLocl, it needs to use objects created in the thread, not static objects and objects created outside the thread class. Because objects pass references, objects in the heap are also used in the thread’s working memory. So if one thread modifies, objects in another thread will also be modified.
-
Memory leaks can occur when ThreadLocal is used incorrectly:
1) When a ThreadLocal variable is assigned to null, the created ThreadLocal object will be reclaimed during GC, and the Value stored in the ThreadlLocalMap will not be retrieved. Memory leakage occurs.
2) When assigning a null value to a ThreadLocal variable, use the threadlocal.remove () method to remove the ThreadLocal.
3) ThreadLocalMap is reclaimed after the thread completes execution.