Pessimistic lock and optimistic lock and detailed explanation

Pessimistic lock and optimistic lock

The optimistic lock corresponds to the optimistic people in life who always think about things going for the better, and the pessimistic lock corresponds to the pessimistic people in life who always think about things going bad. These two kinds of people have their own advantages and disadvantages, and one kind of person is better than the other depending on the scene.
 

Pessimistic lock

Always assume the worst case. Every time you get the data, you think that others will modify it, so every time you get the data, you will lock it, so that others who want to get the data will block until it gets the lock ( shared resource It is 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., which are all locked before operations. Exclusive locks such as synchronized and ReentrantLock in Java are the realization of the pessimistic lock idea.

 

Optimistic lock

Always assume the best situation. Every time I get the data, I think that others will not modify it, so it will not be locked, but when updating, it will be judged whether others have updated the data during this period. You can use the version Number mechanism and CAS algorithm implementation. Optimistic locking is suitable for multi-read application types, which can improve throughput. The mechanism similar to write_condition provided by the database is actually optimistic locking. The atomic variable class under the java.util.concurrent.atomic package in Java is implemented using CAS, an implementation of optimistic locking.

 

Use scenarios of two locks

Optimistic locking is suitable for the case of fewer writes (read more scenarios), that is, when conflicts really rarely occur, which can save the overhead of locking and increase the overall throughput of the system. However, if it is over-write, conflicts will usually occur frequently, which will cause the upper-level application to constantly retry, which will reduce performance, so it is more appropriate to use pessimistic lock in the scenario of over-write.
 
 

Two common implementations of optimistic locking

Optimistic locking is generally implemented using the version number mechanism or CAS algorithm.
 

1. Version number mechanism

Generally, a data version number version field is added to the data table to indicate the number of times the data has been modified. When the data is modified, the version value will increase by 1. When thread A wants to update the data value, it will also read the version value while reading the data. When submitting the update, if the version value read just now is equal to the version value in the current database, it will update, otherwise try again Update operation until the update is successful.

A simple example: Suppose there is a version field in the account information table in the database, the current value is 1; and the current account balance field (balance) is $100.

  1. Operator A reads it out (version=1) and deducts $50 ($100-$50) from his account balance.
  2. During the operation of operator A, operator B also reads this user information (version=1) and deducts $20 ($100-$20) from his account balance.
  3. Operator A completes the modification work, and submits the data version number (version=1 ), together with the account balance (balance=$50 ), to the database for update. At this time, because the submitted data version is equal to the current version of the database record, the data is updated. The database record version is updated to 2.
  4. Operator B completed the operation and tried to submit data to the database (balance=$80) with the version number (version=1 ), but at this time, when comparing the database record version, it was found that the version number of the data submitted by operator B was 1. The database The current version of the record is also 2, which does not meet the optimistic locking strategy of "The submitted version must be equal to the current version to perform the update". Therefore, the submission of Operator B is rejected.

In this way, it is avoided that operator B overwrites the operation result of operator A with the result of old data modification based on version=1.

 

2. CAS algorithm

Namely compare and swap (compare and swap), is a well-known lock-free algorithm. Lock-free programming, that is, to achieve variable synchronization between multiple threads without using locks, that is, to achieve variable synchronization without threads being blocked, so it is also called non-blocking synchronization (Non-blocking Synchronization). The CAS algorithm involves three operands

  • Need to read and write memory value V
  • The value to compare A
  • New value to be written B

If and only if the value of V is equal to A, CAS atomically updates the value of V with the new value B, otherwise no operation will be performed (comparison and replacement are an atomic operation). Under normal circumstances, it is a spin operation, that is, constant retry.
 
 

Disadvantages of optimistic locking

1. ABA problem

If a variable V is the value of A when it is first read, and it is checked that it is still the value of A when it is ready to be assigned, can we show that its value has not been modified by other threads? Obviously it can't, because during this time its value may be changed to another value, and then changed back to A, then the CAS operation will mistakenly believe that it has never been modified. This problem is called the "ABA" problem of CAS operation.

2. Long cycle time and high overhead

Spin CAS (that is, it will execute in a loop until it is successful) if it is unsuccessful for a long time, it will bring a very large execution overhead to the CPU.

3. Only guarantee the atomic operation of a shared variable

CAS is only valid for a single shared variable. CAS is invalid when the operation involves multiple shared variables.
 
 

Use scenarios of CAS and synchronized

Simply put, CAS is suitable for less writes (more read scenarios, generally less conflicts), synchronized is suitable for more writes (more write scenarios, generally more conflicts)

  1. In the case of less resource competition (light thread conflicts), the use of synchronized synchronization locks for thread blocking and wake-up switching, as well as switching operations between user mode and kernel mode wastes cpu resources; CAS is based on hardware and does not need to enter the kernel. There is no need to switch threads, and the chance of operating spin is less, so higher performance can be obtained.
  2. In the case of serious resource competition (serious thread conflict), the probability of CAS spinning is relatively large, which wastes more CPU resources and is less efficient than synchronized.

Guess you like

Origin blog.csdn.net/weixin_43901865/article/details/112792487