pessimistic lock, optimistic lock, spin lock

pessimistic lock, optimistic lock, spin lock

(1) Optimistic lock

Optimistic locking is an optimistic idea, that is, it believes that more reads and less writes, and the possibility of encountering concurrency is low. Every time the data is fetched, it is assumed that others will not modify it, so it will not be locked. However, when updating, it will judge whether others have updated the data during this period. It can be realized by using the version number mechanism (or timestamp) and the CAS algorithm.

Optimistic locks in Java are basically implemented through CAS operations. CAS is an atomic update operation that compares whether the current value is the same as the incoming value. If they are the same, they will be updated, otherwise they will fail.

–> Disadvantages:

  • ABA questions:

CAS can cause "ABA problems". An important prerequisite for the implementation of the CAS algorithm is that the data in the memory at a certain moment needs to be taken out, and compared and replaced at the next moment, then the time difference will cause the data to change.

Part of the implementation of optimistic lock is to solve the ABA problem through the version number (version). Optimistic lock will carry a version number every time the data modification operation is performed. Once the version number is consistent with the data version number, the modification operation can be performed and the version number +1 operation is performed. Otherwise, the execution will fail, because the version number of each operation will increase accordingly, so there will be no ABA problem.

  • Atomic operations can only be guaranteed for one shared variable

CAS is only valid for a single variable, but CAS is invalid when multiple shared variables are involved

(2) Pessimistic locks
Pessimistic locks are pessimistic thinking, that is, they think that if there are many writes, the possibility of encountering concurrency is high. Every time you get data, you will think that others will modify the data, so you will lock it every time you read data, so that when others want to read and write this data, it will block until you get the lock. (Shared resources are only used by one thread at a time, other threads are blocked, and the resources are transferred to other threads after use). Many such locking mechanisms are used in traditional relational databases, such as row locks, table locks, etc., read locks, write locks, etc., all of which are locked before operations are performed.

The pessimistic lock in Java is Synchronized. The lock under the AQS framework first tries the CAS optimistic lock to acquire the lock. If it cannot be acquired, it will be converted into a pessimistic lock, such as ReentrantLock

Scenarios for using the two types of locks
Optimistic locking is suitable for situations where there are many reads and few writes, that is, when conflicts really rarely occur, this can save the overhead of locking and increase the overall throughput of the system. However, if there are many writes, conflicts will often occur. When the lock acquisition fails, the spin operation must be performed continuously to try to acquire the lock again, which will lead to performance degradation. Therefore, it is more appropriate to use pessimistic locks in the scenario of many writes.

(3) Spin
lock The principle of spin lock is very simple. If the thread holding the lock can release the lock resource in a short period of time, then those threads waiting for the competing lock resource do not need to switch between the kernel state and the user state to enter the blocking and suspending state.

Thread spin needs to consume CPU. To put it bluntly, it is to let the CPU do useless work. If the lock cannot be obtained, the thread cannot always occupy the CPU to spin and do useless work. Therefore, it is necessary to set a maximum spin waiting time.

Advantages and disadvantages:

Spin locks reduce thread blocking as much as possible, which greatly improves the performance of code blocks that do not have intense lock competition and occupy a very short lock time, because the consumption of spin will be less than the operation consumption of thread blocking, suspending and waking up, and these operations will cause the thread to switch context twice!

But if the lock competition is fierce, or the thread holding the lock needs to occupy the lock for a long time to execute the synchronization block, it is not suitable to use the spin lock at this time, because the spin lock always occupies the CPU to do useless work before acquiring the lock, occupying XX not XX, and a large number of threads competing for a lock at the same time will lead to a long time for acquiring the lock. So in this case we have to turn off the spin lock.

In-depth understanding of CAS

public class casDemo {
    //CAS : compareAndSet 比较并交换
    public static void main(String[] args) {
        AtomicInteger atomicInteger = new AtomicInteger(2020);

        //boolean compareAndSet(int expect, int update)
        //期望值、更新值
        //如果实际值 和 我的期望值相同,那么就更新
        //如果实际值 和 我的期望值不同,那么就不更新
        System.out.println(atomicInteger.compareAndSet(2020, 2021));
        System.out.println(atomicInteger.get());

        //因为期望值是2020  实际值却变成了2021  所以会修改失败
        //CAS 是CPU的并发原语
        atomicInteger.getAndIncrement(); //++操作
        System.out.println(atomicInteger.compareAndSet(2020, 2021));
        System.out.println(atomicInteger.get());
    }
}

Unsafe class

insert image description here

image-20200812220411463

Summarize:

CAS: Compare the value in the current working memory with the value in the main memory, if the value is expected, then perform the operation! If not, it keeps looping, using a spin lock.

shortcoming:

  • Loops take time;
  • The atomicity of only one shared variable can be guaranteed at a time;
  • it will have ABA problem

To solve the ABA problem, the corresponding idea is to use optimistic lock~ -------> atomic operation with version number !
 

 

 

Guess you like

Origin blog.csdn.net/m0_69057918/article/details/131051979