当前位置:网站首页>JVM (VIII) Thread safety and lock optimization

JVM (VIII) Thread safety and lock optimization

2022-06-12 10:02:00 A god given dream never wakes up

JVM( 8、 ... and ). Thread safety and lock optimization

1. summary

Program runs fast , You may need efficient concurrency , The problem is thread safety ;

2. Thread safety

When multiple threads access an object at the same time , If you don 't have to consider the scheduling and alternate execution of these threads in the runtime environment , There's no need for extra synchronization , Or any other coordination operation at the caller , The behavior of calling this object can get the correct result , This object is called thread safe ;

2.1 Java Thread safety in

1. Immutable object : such as String, Enumeration type , Basic type of packaging class ;

2. Absolute thread safety : It's hard to achieve

3. Relative thread safety : Java in Vector、HashTable、Collections Of synchronizedCollection()

4. Thread compatibility : By using the synchronization method correctly at the calling end, the objects can be safely used in the concurrent environment

5. Thread opposition : Whether or not the caller has taken synchronization measures , You can't use code concurrently in a multithreaded environment ( Very few )

2.2 How to achieve thread safety

1. Mutually exclusive synchronization Pessimistic locking

synchronized, Reentrant , Cannot force a thread that has acquired a lock to release the lock , A thread waiting for a lock cannot be forced to interrupt waiting or to time out

Holding a lock is a heavyweight operation ,Java Threads are operating system based implementations , To wake up or block another thread , You need the operating system to help , This will involve the transformation of user state and nuclear state of mind ,CPU Time consuming operations ( The following virtual machines will also be optimized , Will notify the operating system to add a spin process before , Avoid frequent exchanges with core states )

ReentrantLock And synchronized Compared with, it adds some advanced functions , There are mainly the following three items : Wait for interruptible 、 Fair locks can be implemented and locks can be bound to multiple conditions

Compare the two ,synchronized It's simpler , Clear , Even if an exception occurs, the virtual machine will be locked ( In the bytecode chapter, it is said that the instructions produced after compilation of this keyword during compilation ); Lock Need to be in finally Forced release of lock in ; And the virtual machine keeps on synchronized The optimization of lock is made , Recommended synchronized

2. Nonblocking synchronization Optimism lock

Optimistic concurrency strategy based on conflict detection , In layman's terms Just ignore the risk , Do it first , If there are no other threads competing for shared data , Then the operation is directly successful ; If the shared data is indeed contested , There was a conflict , Then take other compensation measures , The most common remedy is to keep trying again , Until there is shared data without competition ; Corresponding to CPU z The instructions are

  • Test and set up (Test-and-Set);
  • Get and add (Fetch-and-Increment);
  • In exchange for (Swap);
  • Compare and exchange (Compare-and-Swap, Hereinafter referred to as CAS);
  • Load link / Conditional storage (Load-Linked/Store-Conditional, Hereinafter referred to as LL/SC)

stay IA64、x86 Useful in the instruction set cmpxchg Command complete Of CAS function

3. No synchronization scheme

Thread local storage (Thread Local Storage)Thread Local

3 Lock the optimization

Adaptive spin (Adaptive Spinning)、 Lock elimination (Lock Elimination)、 Lock expansion (Lock Coarsening)、 Lightweight lock (Lightweight Locking)、 Biased locking (Biased Locking) etc. , These technologies are designed to share data more efficiently between threads and solve the competition problem , So as to improve the execution efficiency of the program

3.1 Spin lock and adaptive spin

As mentioned earlier synchronized In case of lock contention, the operating system thread switching and wakeup will not be applied immediately , There is a state of spin , Will last for a short time , Just to make the thread wait for a while , This is called a spin lock , stay JDK 6 It has been changed to on by default , The number of spins is usually 10 Time , Spin is also consumed CPU Of , So if the lock is occupied for a short time , The spin wait effect will be very good , On the contrary, if the lock is occupied for a long time , The spinning thread will only consume the processor resources in vain , Instead of doing any valuable work , This leads to a waste of performance ;

If a thread acquires a lock during the self selection period , Then the virtual machine will think that the next lock competition will spin , Then allow the spin time to get longer , Like spin 100 Time ;

But if spin rarely gains lock , Then the process of acquiring the lock in the future is likely to be the process of directly ignoring the spin , avoid CPU Waste of resources ;

3.2 Lock elimination

The concatenation of strings is always done by generating new String Object to carry on , therefore Javac The compiler will String Connection to do automatic optimization

    public static void main(String[] args) {
    
        String test = "haha";
        for (int i = 0; i < 1000; i++) {
    
            test = test+"niubi";
        }
    }
    LINENUMBER 10 L4
    NEW java/lang/StringBuilder
    DUP
    INVOKESPECIAL java/lang/StringBuilder.<init> ()V
    ALOAD 1
    INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;
    LDC "niubi"
    INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;
    INVOKEVIRTUAL java/lang/StringBuilder.toString ()Ljava/lang/String;
    ASTORE 1

3.3 Lock coarsening

If a series of continuous operations repeatedly lock and unlock the same object , Even the locking operation occurs in the loop body , Even if there is no thread race , Frequent mutex synchronization also leads to unnecessary performance loss , Range extension of lock synchronization ( Coarsening ) To the outside of the entire sequence of operations ;

3.4 Lightweight lock

Object header information ( The first 2 In the chapter ),Mark Word Designed as a non fixed dynamic data structure

[ Failed to transfer the external chain picture , The origin station may have anti-theft chain mechanism , It is suggested to save the pictures and upload them directly (img-pnMqzhwi-1645544509863)(D:\Resource\note\JVM\png\8\1.png)]

The process of locking

1. The code is about to enter the synchronization block , If the object is not locked (01), The virtual machine is established in the stack frame of the current thread Lock Record Store the current lock object Mark Word( Namely Hash age It was stored in a different place , Use it up and change it back ) , And lock object references , Update lock flag bit by 00

2.CAS Try to put the object's Mark Word 32bit Update to point Lock Record The pointer to , If you fail , There is thread contention , The lock is occupied by another thread ; If the lock object Mark Word Stack frame pointing to the current thread , Go directly to the synchronization block to continue execution ( notes : Each time you enter, you need to create a Lock Record A record is a repeated entry of a thread It is also the optimization direction of the lock )

Two or more threads contend for the same lock ; The lightweight lock is no longer valid , It has to be expanded into a heavyweight lock , The status value of the lock flag becomes “10”

Unlocking process

Object's

Mark Word Still point to the thread's lock record , Then use **CAS( The spin )** The operation sets the object's current Mark Word And copied in threads Displaced Mark Word Replace it with ( Principle hash age Change back )

If we can successfully replace , Then the whole synchronization process is completed successfully

If the substitution fails , Other threads have tried to acquire the lock , Just as you release the lock , Wakes up the suspended thread

3.5 Biased locking

As mentioned above, even if a thread repeatedly enters itself, it needs to generate lock record replacement Mark Word, With the deflection lock Only for the first time CAS The thread ID Set to the object Mark Word head , And then I found out This thread ID It means there is no competition , There is no need to CAS

Use at the same time CAS Operation to get the lock to the thread Of ID Record in object Mark Word In . If CAS Successful operation , Every time the thread holding the biased lock enters the lock related synchronization block later , Virtual machines can no longer do any synchronization ;

Once another thread tries to acquire the lock , The biased pattern ends immediately . According to the lock object, it is No is in the locked state, which determines whether to revoke the bias ( The bias mode is set to “0”), After revocation, the flag bit is restored to unlocked ( Sign a by “01”) Or lightweight locking ( Sign bit is “00”) The state of , The subsequent synchronization operations are performed as described above for lightweight locks

A lock , The biased pattern ends immediately . According to the lock object, it is No is in the locked state, which determines whether to revoke the bias ( The bias mode is set to “0”), After revocation, the flag bit is restored to unlocked ( Sign a by “01”) Or lightweight locking ( Sign bit is “00”) The state of , The subsequent synchronization operations are performed as described above for lightweight locks

notes :hash And bias can only use one , When an object has calculated a consistent hash code , It can no longer enter the bias lock state ; When an object is currently in a biased lock state , When receiving a request to calculate its consistent hash code , Its biased state will be revoked immediately , And the lock will expand into a heavyweight lock ;

原网站

版权声明
本文为[A god given dream never wakes up]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/03/202203010528446340.html