[Database transactions and locks] in detail eight: a way to realize the optimistic lock of database transaction--cas

Source: Internet
Author: User
Tags cas volatile

Note: This article is reproduced from http://www.hollischuang.com/archives/1537

We introduced the lock in depth understanding of optimism lock and pessimistic lock article. Based on this article, this paper analyzes the implementation mechanism of optimistic lock, introduces the application of CAs and CAs, and the problems existed in CAs.

Thread Safety

As we all know, Java is multi-threaded. However, Java support for multithreading is actually a double-edged sword. When more than one thread is involved in the sharing of resources, it can cause thread safety problems when handled poorly. Thread safety can be very complex, and in the absence of sufficient synchronization, the order in which operations are performed in multiple threads is unpredictable.

The main way to do multi-threaded communication in Java is to share the memory, the main focus of shared memory is two: visibility and order. In addition to the atomicity of the compound operation, we can assume that Java's thread-safety issues focus on 3 key points: visibility, ordering, and atomicity.

The Java Memory model (JMM) solves the problem of visibility and ordering, and locking solves the problem of atomicity. Other relevant knowledge of JMM and locks is no longer detailed here. But we have to discuss the question of whether the lock is good or not.

Problems with Locks

Java is guaranteed to be synchronized by synchronized keyword before JDK1.5, which uses a consistent locking protocol to coordinate access to shared state, ensuring that regardless of which thread holds a lock on a shared variable, the variables are accessed in an exclusive way. Exclusive lock is actually a pessimistic lock, so it can be said to synchronized be pessimistic lock.

The pessimistic locking mechanism has the following problems:

In the multi-threaded competition, locking, releasing locks can cause a lot of context switching and scheduling delay, causing performance problems.

Holding a lock on one thread causes all other threads that require this lock to hang.

If a thread with a high priority waits for a thread with a lower priority to release the lock, it causes the priority to be inverted, causing a performance risk.

Another more effective lock is the optimistic lock. The so-called optimistic lock is that each time without locking but assuming that there is no conflict to complete an operation, if the conflict failed to retry until successful.

volatilevariables are a more lightweight synchronization mechanism than locks, because context switches and thread scheduling do not occur when using these variables, but they do not volatile solve atomicity problems, so variables cannot be used when a variable relies on the old value volatile . Therefore, for synchronization to eventually return to the lock mechanism.

Optimistic lock

Optimistic locking ( Optimistic Locking ) is actually a kind of thought. Relative pessimistic lock, optimistic locking hypothesis that the data generally do not cause conflict, so when the data is submitted to update the data will be formally conflicting or not detected, if a conflict is found, let the user return the wrong information, let users decide how to do.

The concept of the optimistic lock mentioned above has actually elaborated on his specific implementation details: The main is two steps: conflict detection and Data update. One of the more typical implementations is compare and Swap ( CAS ).

Cas

CAS is an optimistic locking technique that when multiple threads try to update the same variable simultaneously using CAS, only one of the threads can update the value of the variable, and the other threads fail, and the failed thread is not suspended, but is told that the competition has failed and can try again.

The CAS operation consists of three operands-the memory location (V), the expected original value (A), and the new value (B). If the value of the memory location matches the expected original value, the processor automatically updates the location value to the new value. Otherwise, the processor does nothing. In either case, it will return the value of that location before the CAS directive. (In some special cases of CAs, only the CAS will be returned successfully, not the current value.) CAS effectively illustrates that "I think position V should contain a value of A; If you include this value, B will be placed in this position; otherwise, do not change the position, just tell me the value of this position now." This is in fact the same principle as the optimistic lock conflict check + data update.

Here again, optimistic locking is an idea. CAS is a way of realizing this idea.

Support for CAs in Java

New in JDK1.5 java.util.concurrent (J.U.C) is built on top of CAs. Compared to synchronized this blocking algorithm, a common implementation of CAS is a non-blocking algorithm. Therefore, the J.U.C has a great improvement in performance.

For example, let's take a java.util.concurrent AtomicInteger look at how to ensure thread safety without using locks. The main understanding getAndIncrement method, the function of the method is equivalent to the ++i operation.

 public  atomicinteger< Span class= "PLN" > extendsnumber  Java. io. serializable {    
1     Private volatile intvalue; 2 3      Public Final intget () {4         returnvalue; 5     }  6 7      Public Final intgetandincrement () {8          for (;;) {  9             intCurrent =get (); Ten             intNext = current + 1;  One             if(Compareandset (current, next)) A                 returnCurrent ;  -         }   -     }   the  -      Public Final BooleanCompareandset (intExpectintupdate) {   -         returnUnsafe.compareandswapint ( This, Valueoffset, expect, update);  -     }   +}

field value is required without locking mechanism to ensure that data between threads is visible by means of the volatile primitive. This can be read directly when the value of the variable is obtained. And see ++i how it's done.

getAndIncrementWith CAS operations, each time the data is read from memory and then the data and +1 the results are CAS-returned, if successful, the result is retried until it succeeds. and compareAndSet the use of JNI to complete the operation of CPU instructions.

ABA Issues

CAs can cause "ABA problems".

The CAS algorithm implements an important premise that needs to take out the data at some point in memory, and compare and replace at the next moment, then the time difference class will cause the data to change.

For example, a thread one takes a from the memory location V, when another thread two also takes a from memory, and two does something to B, and two then turns the data in the V position into a, when the CAS operation finds that the memory is still a, and then the one operation succeeds. Although the CAS operation of thread one is successful, it does not mean that the process is not a problem.

Partial optimistic lock implementation is through the version number ( version ) to solve the ABA problem, optimistic lock every time you perform the modification of the data, will take a version number, once the version number and the version number of the data are consistent can be modified and the version number to perform +1 operations, otherwise the execution fails. Because the version number of each operation increases with it, there is no ABA problem because the version number will only increase and will not decrease.

Summarize

Thread-safety issues in Java are critical, and locking mechanisms are needed to ensure thread safety. The locking mechanism consists of two types: optimistic and pessimistic. Pessimistic locks are exclusive locks, which block locks. An optimistic lock is a non-exclusive lock, not a blocking lock. One way to implement optimistic locking is CAs, which is widely used in JDK 1.5 java.util.concurrent . However, it is important to note that there is an ABA problem with this algorithm.

CAs and object creation

In addition, CAS has an application that is in the process of creating objects in the JVM. Object creation is very frequent in virtual machines. Even if you just modify the position that a pointer points to, it is not thread-safe in concurrency, it may be allocating memory space to object A, the pointer has not been modified, and object B uses the original pointer to allocate memory. There are two ways to solve this problem, one of which is to use CAS with failed retries to ensure the atomicity of the update operation.

Resources

Non-blocking synchronization algorithm and CAS (Compare and Swap) lock-free algorithm

CAS principle Analysis

Java CAS and ABA issues

[Database transactions and locks] in detail eight: a way to realize the optimistic lock of database transaction--cas

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.