1. The concept of locks in JAVA
-
Spin Lock: When a thread acquires a lock, if the lock has already been acquired by another thread, the thread will wait in a loop and constantly determine if the lock can be acquired successfully until it is acquired.
-
Optimistic lock: If there is no conflict, read the latest data when modifying the data and retry the modification if you find that the data is different from what you previously obtained.
-
Pessimistic locks: If concurrent conflicts occur, synchronize all operations related to the data and lock the data as soon as it is read.
-
Exclusive Lock (Write): Add a write lock to a resource so that the thread can modify the resource and no other threads can lock it again; (Single Write)
-
Shared Lock (Read): When a read lock is added to a resource, it can only be read and not changed, and other threads can only add and write locks; (Multiple Read)
-
Re-lockable, non-re-lockable: Once you have a lock, you are free to enter other code synchronized by the same lock.
// Re-Lockable Code Demo public class Demo1_ReentrantTest { private static int i = 0; private final static Lock lc = new ReentrantLock(); // Re-lockable public static void recursive() throws InterruptedException { lc.lock(); i ++; System.out.println("here i am..."); Thread.sleep(1000); recursive(); lc.unlock(); } public static void main(String[] args) throws InterruptedException { recursive(); } }
-
Fair locks, unfair locks: The order in which locks are contested is fair if they come first, then come first.
-
Several important lock implementations: synchronized, ReentrantLock, ReentrantReadWriteLock
2. synchronized keyword
1. Basic Introduction
- When used for instance and static methods, the lock object is implicitly specified.
- When used for code blocks, the specified lock object is displayed.
- Scope of locks: object locks, class locks, distributed locks.
2. Features: Reentrant, exclusive, pessimistic lock.
3. Lock optimization
-
Lock Removal
- Open Lock Removal Parameters: -XX:+DoEscapeAnalysis-XX:+EliminateLocks)
- Optimizations will take place under a single thread.
// When JIT is compiled on the fly, lock cancellation occurs (JIT compilation is triggered only after a certain number of method calls) public class Demo4_LockElimination { public void test1(Object arg) { // StringBuilder thread is insecure, StringBuffer uses synchronized, is thread safe // jit optimization, eliminating locks StringBuffer stringBuffer = new StringBuffer(); stringBuffer.append("a"); stringBuffer.append("b"); stringBuffer.append("c"); stringBuffer.append("a"); stringBuffer.append("b"); stringBuffer.append("c"); stringBuffer.append("a"); stringBuffer.append("b"); stringBuffer.append("c"); } public static void main(String[] args) { for (int i = 0; i < 100000; i ++) { new Demo4_LockElimination().test1("123"); } } }
-
Lock coarsening
- JDK optimizes lock coarsening, but we can optimize it at the code level.
- Optimizations are also made under multiple threads.
// Lock coarsening (runtime jit compilation optimization) public class Demo5_LockCoarsening { // If the following code is called multiple times, triggering jit compilation, it may be jit optimized for code like the test2 method public void test1(Object arg) { int i = 0; synchronized (this) { i ++; } synchronized (this) { i --; } // If this step is a time-consuming operation, it may not be optimized System.out.println("dsfsadssffs"); synchronized (this) { System.out.println("werkdfjskf"); } synchronized (this) { i ++; } } public void test2(Object arg) { int i = 0; synchronized (this) { i ++; i --; System.out.println("dsfsadssffs"); System.out.println("werkdfjskf"); i ++; } } }
4. Note
- synchronized keyword, not only synchronization.
- In JMM, synchronized ensures visibility (cannot be cached).
3. Java objects in heap memory
1. Heap memory storage display
public class Demo5_Main { public static void main(String[] args) { int a = 1; Teacher kody = new Teacher(); kody.stu = new Student(); } } class Teacher { String name = "Kody"; int age = 40; boolean gender = true; Student stu; } class Student { String name = "Emily"; int age = 18; boolean gender = false; }
2. Object Header Mark Word
-
By default, JVM locks experience four states: unlocked->biased->lightweight->heavyweight.
-
Reference material:
- https://www.cs.princeton.edu/picasso/mats/HotspotOverview.pdf
- https://wiki.openjdk.java.net/display/HotSpot/Synchronization
- Deep understanding of Java virtual machines
3. Lightweight lock
- In an unlocked state, CAS can be used to lock, and a lightweight lock is seized
4. Heavy Lock
- Key points: owner, lock pool, wait pool
- The spin in a lightweight lock has a certain number of times limit, exceeding the number limit, and the lightweight lock is upgraded to a heavy lock.
5. Deflection lock
- After JDK6, the optimization of bias locking has been turned on by default, and it is disabled by the JVM parameter -XX:UseBiasedLocking.
- If the bias lock is opened, only one thread is locked to obtain the bias lock.