006. Thread-safe JAVA lock correlation

Posted by JakesSA on Sun, 05 Apr 2020 02:55:32 +0200

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

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.

6. Upgrade process of locks

Topics: Programming Java jvm JDK