CAS and AQS of concurrent programming in java

The Spring Festival is about to be celebrated in one month. After the Spring Festival, it’s time to change jobs once a year. In particular, programmers can only rely on job-hopping to ensure that the salary can reach the average level of the market. In the interview, CAS AQS and AQS are also frequently asked questions in interviews. I hope that friends who are going to change jobs next year can use them in interviews.

CAS: Compare And Swap means more replacement. In multi-threaded concurrency, we can use locks to ensure thread safety. However, using the lock mechanism can also cause performance problems. For example, using Synchornized will cause thread blocking problems. CAS is To solve this problem came into being. A large number of APIs in jdk use CAS to solve the thread safety problem in multi-threading. Let's look at the use of CAS through an atomic class. AtomicInteger is an atomic class that uses CAS, let's look at it through the source code.

From the source code of AtomicInteger, you can see that the internal implementation of the compareAndSet() method is actually implemented by the compareAndSwapInt() method under the unsafe class. The methods at the beginning of these compareAndSwap are implemented based on CAS. Unsafe provides hardware-level atomic operations. Realizing CAS, what exactly is CAS?

CAS includes three operands: memory location, expected original value, and new value. If the value of the memory location matches the expected original value, then the value of the memory location is updated to the new value, otherwise the processor does nothing. CAS indicates that the processor believes that the memory location should contain the expected original value, and if it does, the new value is placed in this location, otherwise the value at that location is returned.

However, there is a problem with CAS, which is the well-known ABA problem. If friends who don’t know ABA, listen to me and tell you slowly, if there is a thread 1 that performs calculations on a value A, it has not been operated on thread 1. Upon completion, thread 2 changes the value to B, and then another thread 3 changes B to A. At this time, thread 1 is calculated, and then it checks A through CAS and finds that the memory value is equal to the original value. The calculated value is updated.

This is the ABA problem. The reason for this problem is that there is no difference between the A in the original memory and the later A, so I don't know that this has been modified. Later, Java provides the AtomicStampedReference class to solve the ABA problem of CAS. The solution is to add a version number to the value to distinguish whether it has been modified.

This is CAS. As for how it is designed at the hardware level, it is not our consideration for the time being.

So what is AQS?

AQS: Abbreviation of AbstractQueuedSynchronizer, AQS is a synchronization framework that provides atomic management of synchronization state, blocking function, thread wake-up function, and queue.

The idea of ​​AQS is to set the currently requested thread as a valid thread if the requested shared resource is free, and lock the shared resource. When other threads request, the shared resource is occupied, and the request thread is put Enter the queue to wait. If the effective thread task is completed, the threads in the queue are set as effective threads in order. In AQS, the state defaults to 0, which means that no thread is locked. If the lock is already locked, state = 1, and the effective thread defaults to null. If there is a locked thread, the effective thread is the locked thread, and the waiting queue is stored waiting. Threaded. We use ReentrantLock to understand the principle of AQS, the following figure is the default state.

If thread 1 is locked, then Thread1 will use CAS operation to make AQS state = 1, and the effective thread is equal to thread 1.

If there is now another thread, Thread2 requests shared resources, then Thread checks state = 1, indicating that someone has already added the lock and is not himself. You can see through the effective thread that Thread1 is occupying the lock, then Thread2 is adding If the lock fails, it will enter the waiting queue for queuing. After the logic execution of Thread1 is completed, Thread will use the CAS operation to set the state to 0, then completely release the lock, set the effective thread to null, and Thread2 itself can again Try to lock up.

Seeing this, everyone should understand what AQS is. AQS is a basic component that contains state variables, waiting queues, etc., used to handle concurrency, and is used to implement various locks and various synchronization components.

Guess you like

Origin blog.csdn.net/wzs535131/article/details/103796488