Pessimistic and optimistic locks and CAS and Synchronized

Pessimistic lock and optimistic lock

What is a pessimistic lock?

The so-called pessimistic lock always assumes the worst case. Every time you go to get the data, you will think that others will modify the data, causing phantom reads, non-repeatable reads, dirty reads, etc., so every time you take the data Locking, shared resources are only used by one thread at a time, causing other threads to block. After use, transfer resources to other threads. Exclusive locks such as synchronized and reentrant-lock in Java are the realization of pessimistic locking ideas.

This lock mechanism, used in row locks, table locks, read locks, and write locks, is also locked before operation.

What is optimistic locking?

The so-called optimistic lock, pay attention to the assumption of the best situation, every time you go to get the data, you think that others will not modify it, so it will not be locked, but it will judge whether there is any change in this data during the update, and use the version number mechanism Implemented with the CAS algorithm, optimistic locking is suitable for multi-read application types, which can improve throughput;

If there is a conflict, retry if there is a conflict, and enter the spin operation until it succeeds. The mechanism used by the optimistic lock is CAS;

The database provides a write-condition mechanism similar to the optimistic lock provided. In java, the atomic variable class under the java.util.concurrent.atomic package uses CAS, which is an implementation of optimistic lock.

Two common implementations of optimistic locking

Version number mechanism:

Generally, a data version number wersion (version) field is added to the data table, indicating the number of times the data is modified. When a thread A wants to update the data, it will also read the version value while reading the data, and then submit To determine whether the currently updated version is the same as the version number retrieved by thread A for the first time to determine whether there is a right to update. After the update version ++, if it does not meet the conditions, it cannot be updated, spin operation, and keep retry ;

CAS algorithm:

CAS (Compare And Swap) comparison and replacement

Use three basic operands: memory address V (the value to be operated), the old expected value A (that is, put the value to be operated into A first, the same as stored in memory), the new value to be modified B;

Working principle: when thread A wants to increase the value of a data by 1, assuming that memory address V is equal to 10, the old expected value is to copy a value of memory address V, the old expected value A is also equal to 10, when thread A When not submitted yet, thread B increases this value by 1 and commits. The value of memory address V is now 11. When thread A commits, compare memory address V = 11 with the old expected value A = 10, A is not equal to The actual value of V, the submission failed;

Thread A will perform a spin operation and will re-acquire the value of memory address V again. The second time, compare V and A. If they are equal, thread A performs SWAP and replaces the value of address V with the new value B;

CAS mechanism Application:

Atomic series, the low-level implementation of the Lock series, java1.6 and above, before the Synchronized is converted into a heavyweight lock, the CAS mechanism will also be used;

CAS mechanism shortcomings:

1. large memory overhead , because the spin state will enter the unsuccessful use, higher than the concurrent case, the cycle, CPU will bring a lot of pressure.

2. not guarantee the atomicity of code blocks , CAS mechanism only to ensure a variable atomic operation is not guaranteed atomicity entire code block, a plurality of variables such as the need to ensure that updates atoms, they would have to use the Synchronized.

3.ABA problem , the biggest problem is the mechanism of CAS, CAS is the use of the mechanism, when the old expectations A and V are the same memory address, can not guarantee that this data is not accessible and not modified, but the value has not changed , This is the ABA problem;

But after the JDK1.5, the AtomicStampedReference class solved this problem, because inside this class, the CAS mechanism in the AtomicReferencele class has an additional timestamp. When updating, the timestamp must also be updated. When the address V and the timestamp both meet the equal condition, the writing will succeed, so even if there is an ABA problem, the object is repeatedly read and written, and then written back to the original value, as long as the timestamp changes, it can prevent inappropriate writing .

Use scenarios for optimistic and pessimistic locks

Optimistic lock is suitable for the case where there are few writes (multi-read scenario). In the case where conflicts rarely occur, it saves the overhead of the lock and increases the overall throughput of the system.

The pessimistic lock is suitable for multi-write situations, where conflicts often occur. If optimistic locks are used, if the conflict occurs, the submission fails, it will continue to spin, occupying a lot of memory, and use pessimism in all general write-over scenarios. The lock is more appropriate.

CAS和synchronized

What is a synchronized lock?

Synchronized synchronization lock makes the operation an atomic operation and realizes thread safety. The Synchronized keyword will make the thread that does not have the lock resource enter the BLOCKED (blocking) state, and then recover the RUNNABLE state after competing for the lock resource. The process involves Operating system user mode and kernel mode conversion, the cost is high;

For java1.6 and above, CAS mechanism will also be used before Synchronized is converted into a heavyweight lock;

After jdk1.6, the Synchronized lock has been optimized to adapt to the spin lock (spin lock: to reduce the consumption caused by the change of the thread state, the current operation is constantly performed), the lock is eliminated (there is no possibility of shared data competition Locks are eliminated intensively , coarsening of locks (continuous locks will be reduced to only one lock), lightweight locks (under conditions of competition, synchronization and mutual exclusion are eliminated through CAS), biased locks (under conditions of competition, elimination The entire synchronization is mutually exclusive, even CAS does not operate).

underlying synchronized implementation mainly depends Lock-Free queue, the basic idea is the spin obstruction, continue to compete lock switch after the competition, a little at the expense of fairness, but received a high throughput, in case of conflict fewer threads, Performance similar to CAS can be obtained. In the case of serious thread conflicts, the performance is much higher than CAS.

Atomic operation class replaces synchronous lock

Under the java.util.concurrent.atomic package, wrapper classes beginning with Atomic, such as AtomicBoolean and AtomicInteger, are used for atomic operations of boolean and integer types, respectively. After use, they can achieve the effect of Synchronized synchronization lock. In this case, the performance of the code will be better than Synchronized, the bottom of the Atomic operation class is to use the CAS mechanism of optimistic locking;

Use cases of CAS and synchronized

In the case of low resource competition, synchronized synchronization locks perform thread blocking and wake-up switching, as well as switching operations between user state and kernel state, which consumes additional CPU. CAS is based on hardware and does not need to enter the kernel and does not require switching Threads have less chance of operating spins, so performance is higher.

In the case of serious resource competition, the probability of CAS spin is relatively large, wasting CPU resources, and the efficiency is lower than synchronized.

Published 5 original articles · praised 4 · visits 18

Guess you like

Origin blog.csdn.net/qq_45218334/article/details/105618508