Java Concurrency principle unraveling, read-write locks ReadWriteLock achieve in-depth analysis

About Read-Write Lock

The previous section we analyze the syntax of the Java JDK level synchronized lock and built-reentrant lock ReentrantLock, we can control access to resources through their multi-threaded scenarios to achieve thread safety. Both locks are part of a purely exclusive lock, which means that any time these locks can only be held by a thread, other threads had to line up in order to acquire the lock.

In order to improve concurrency we will be purely an exclusive lock some scenes reform, the introduction of additional shared lock to constitute a common external lock and exclusive lock, which is called read-write locks. Why is it called read-write lock it? Mainly because it takes into account the use of reading and writing scenes, is generally believed that reading will not change the data read operation can be multi-threaded, but a write operation to change the data so only one thread writes. Read-write lock internally maintains a pair of lock (read and write locks), which is separated by the lock to obtain higher concurrency performance.

Below, there is a write lock object, which contains internal read and write locks two objects. If five threads in which threads and thread two want to get a read lock, so two threads can be acquired at the same time to read lock. But do not write lock can be shared, it is an exclusive lock. Such as thread three threads fourth and five are threads wanted to hold a write lock, then only a thread round the hold.

Read-Write Lock

Nature of the read-write lock

  • Multiple threads can hold the lock successfully acquired a thread after a read lock other threads that still manages to get a read lock, even if the thread does not release the read lock.

A read-write lock Nature
  • In the case of a thread holds a read lock other threads can not hold a write lock, thread unless hold the lock and freed of all read locks.

Properties of read-write lock 2
  • In the case of a thread holds the write lock other threads can not hold a write lock or read lock, a thread successfully acquired a write lock after all other attempts to acquire read and write locks thread will enter the wait state, only when the thread releases the lock after the write down other threads can proceed.

3 Read-Write Lock Properties
  • If we want to get a read lock will need to meet two conditions: There is no thread holds the write lock and currently there is no thread request a write lock.

Read-write lock nature 4
  • If we want to obtain a write lock will need to meet two conditions: There is no thread holds the write lock and currently there is no thread holds a read lock.

5 Read-Write Lock Properties

Simple implementation version

In order to deepen the understanding of the read-write lock before the read-write lock JDK implementation analysis, we first look at a simple version of the read-write lock realize. Wherein three each represent an integer variable number of threads hold read lock and a write lock holds the number of threads and the threads writing request a lock, four methods corresponding read lock, write lock acquisition and release operations. acquireReadLock method used to obtain a read lock, if the number of threads to hold the number of threads write lock or read lock request is greater than 0 so that the thread into a wait state. releaseReadLock method for releasing a read lock, the lock will read the number of threads together Save wake other threads. acquireWriteLock method used to obtain a write lock, if the number of threads to hold a read lock or write lock held by a thread number greater than 0 so that the thread into a wait state. releaseWriteLock method for releasing the write lock, write lock will reduce the number of threads together wake up other threads.

Simple version of the read-write lock

Read locks to write locks upgrade

In some scenes, we want a lock already have read the thread can obtain a write lock, and freed the original read lock, this situation involves a read lock upgraded to a write lock operation. Read-write lock upgrade need to meet certain conditions, this condition is a thread must be the only thread that owns a read lock, otherwise it will not succeed. In the following figure, two thread already holds a read lock, but it is only one thread that holds a read lock, so that it can successfully write lock.

Read lock upgrade

Write lock downgraded to a read lock

With the corresponding lock escalation is a lock downgrade, degrade lock is a write lock threads have already hoping to get a read lock and write lock off the original release. Lock downgrade little risk, because the write lock is an exclusive lock, write lock held by the thread must be the only, and certainly holds a read lock thread does not exist, so write lock can downgrade directly read lock. As shown below, the thread holding three write lock, then other threads can not hold read and write locks, so you can safely write lock down to read lock.

Write lock downgrade

ReadWriteLock Interface

ReadWriteLock is actually an interface that only provides two methods: readLock and writeLock. Respectively, to obtain a read lock on the object and obtain a write lock object, JDK provides a built-in tool for us to read and write locks that ReentrantReadWriteLock class, we will be in-depth analysis. ReentrantReadWriteLock class contains properties and methods more, in order to make clear thinking and analysis to facilitate understanding, we will eliminate non-core source code, only the core function analysis.

ReentrantReadWriteLock three elements

Three elements ReentrantReadWriteLock class are: fair / unfair mode, read and write lock object lock object. Where the fair / unfair pattern indicates whether or not to get a lock first-served basis in accordance with the order of multiple threads at the same time to acquire the lock if it was fair mode, otherwise non-equity mode. Read lock object responsible for implementing the read lock, write lock object is responsible for implementing and write lock functions, which belong to two classes inside class ReentrantReadWriteLock, the following will explain in detail.

ReentrantReadWriteLock realize ideas

Overall, the interior ReentrantReadWriteLock class contains ReadLock WriteLock inner classes and inner classes, corresponding to read and write locks, lock provides both equity and non-equity mode mode. Whether fair or not fair mode mode, either a read lock or a write lock are based AQS synchronizers to achieve. The main difficulty is to realize using only one synchronization object is achieved AQS read and write locks, which requires the read and write locks share the same shared state variable, the following will specifically explain how to use a state variable for the read and write locks lock use.

Realize ideas

ReentrantReadWriteLock class corresponding to the following structure, ReentrantReadWriteLock.ReadLock ReentrantReadWriteLock.WriteLock and objects are read lock and a write lock object. Sync ReentrantReadWriteLock class object represents the synchronizer, which is based AQS synchronization, while FairSync classes represent classes and NonfairSync fair fair mode and a non-synchronized mode, see a non-fair mode is used by default.

Shared write lock state variables

ReentrantReadWriteLock previously mentioned difficulty is that read and write locks share a shared variable, the following is common to see how specific. We know that shared state AQS synchronizer is an integer, that is 32, then the easiest way to share read and write locks were used 16. 16 wherein the high state for a read lock, while the lower 16 bits are used for the write lock state, so that they achieve a common effect. But after this design, when we get to read and write locks state values ​​require some additional calculations, such as some shift and logical operation.

Sharing state variables

ReentrantReadWriteLock synchronizer common logic as state variables, wherein the number of bits SHARED_SHIFT movement is 16; SHARED_UNIT each represents a read lock state value corresponding to the size of the lock, left 16 1 1 exactly corresponds to the high 16 bits; represents MAX_COUNT the maximum number of read locks can be locked, 16 is 1 (binary); EXCLUSIVE_MASK mask for a write lock, 16 is 1 (binary). sharedCount method for acquiring a read lock state value (upper 16 bits), i.e., left 16 can be obtained. exclusiveCount method for acquiring a write lock state values ​​(low 16), that can be obtained by the mask.

ReadLock and WriteLock Profile

And the two elements are ReadLock WriteLock ReentrantReadWriteLock, all of which belong to the inner class ReentrantReadWriteLock. They have achieved Lock interface, we mainly focus lock, unlock and newCondition these core methods. The operation of the lock respectively read and write locks, and release the lock operation and create Condition objects operation, you can see these methods are called indirect method synchronizer ReentrantReadWriteLock, note that read lock does not support the creation of Condition objects. We reentrant lock ReentrantLock chapters have been explained Condition objects, this section will not repeat them.

Fair / unfair mode

A non-default mode ReentrantReadWriteLock fair mode, the internal class Sync mode FairSync fair fair mode NonfairSync and non-abstract class parent class. Because ReentrantReadWriteLock use of a shared read lock mode, using an exclusive write lock mode, so the parent class fairness mechanism in different modes and abstracted readerShouldBlock writerShouldBlock two abstract methods, and each subclass can implement different modes of fairness . In other words, ReentrantReadWriteLock fair mechanism to be determined by the two methods.

Fairness mode FairSync following classes, readerShouldBlock writerShouldBlock and two direct method in the class method returns the result hasQueuedPredecessors, AQS synchronizer This method is a method for determining whether the current thread has queued in front of the thread. If there is a queue line will allow the current thread to join the queue in the queue, so acquiring the lock will ensure the fairness of the queue according to the order.

Continue to look at non-equity modes NonfairSync class, writerShouldBlock class method directly returns false, show do not let the current thread into the queue queue, directly lock to gain competitive. readerShouldBlock method is called apparentlyFirstQueuedIsExclusive method, which is AQS synchronizer method for determining whether a next node of the head node of the thread in an exclusive lock request (write lock). If you let other threads to obtain a write lock, and while he went obediently line up. If not then the next node is a request for a shared lock thread (read lock), competing directly read lock case.

Fair / unfair

Write achieve the lock WriteLock

The above description, we know WriteLock has two core methods: lock and unlock. They are called indirect method corresponding to the internal ReentrantReadWriteLock synchronizer, the synchronizer is required in the method and override tryAcquire tryRelease methods, respectively, for acquiring a write lock and releasing the write lock operation.

Look tryAcquire logic process, and to give the value of acquisition state write lock state value lower by 16 exclusiveCount method. c! = 0 when two cases, one is the upper 16 bits of the read lock state is not 0, one is the lower 16 bits of the write lock state is not 0. w is equal to 0 means there is thread holds a read lock, direct return false representation to obtain a write lock failed. If the write lock thread for holding the current thread, then the re-write lock operation, then the state variables need to accumulate, in addition to be verified is written into the locked state can not exceed a weight MAX_COUNT. Analyzing method by writerShouldBlock whether the current thread into the queue in the queue, while for accumulation state variables compareAndSetState algorithm method has the CAS, CAS fails then the current thread need to be queued into the queue. For non-equity modes, CAS where the operation is to break into operation, that thread first attempt to compete write lock. Finally, write locks held by the current thread setExclusiveOwnerThread setting, which simply set the variable method.

Continue to look at the logic tryRelease method, first check with isHeldExclusively method must have a current thread thread to write locks. Then the state value minus the value of the release, and with the lower 16 bits write lock state value by exclusiveCount, if a value of 0 indicates no re-entry may have been completely release the lock, call setExclusiveOwnerThread (null) is set to hold no thread write lock. Finally, set a new status value.

Realization of a read lock ReadLock

ReadLock also has two core methods: lock and unlock. They are called indirect method corresponding to the internal ReentrantReadWriteLock synchronizer, the synchronizer is required in the method and override tryAcquireShared tryReleaseShared methods, respectively, for acquiring a read lock and releasing the read lock operation.

Logic tryAcquireShared method: first acquisition status values ​​getState method, and then obtaining the lower 16 bits of the write lock status exclusiveCount method, if not zero indicating that another thread holds the lock and a write current thread does not hold write lock, then At this time, try to get a read lock fails, it returns -1, is about to put the current thread queue queue. Note that if the current thread holds a write lock, then you can continue to get a read lock. SharedCount continued by the upper 16 bits of the read lock, and then attempt to set a new status value CAS algorithm returns 1 if successful read lock is successfully acquired. If unsuccessful, continue to call fullTryAcquireShared method.

Logic fullTryAcquireShared method is: This is an infinite spin operation, first to obtain the status value, if the write lock is not zero and the current thread holds a write lock is not a program, it returns -1, indicating failure of attempts to obtain a read lock, the current threads are queuing queue. If the write lock state is 0, there are no thread holds the write lock, the method determines whether to continue through readerShouldBlock thread needs to be added to the queue in the queue, if necessary, returns -1, AQS synchronizer will add it to the queuing queue in. Additionally, the status value is not equal to the read lock MAX_COUNT, i.e. has reached the maximum number of read locks. Finally, set up a new state value method by compareAndSetState CAS algorithm is here, for infinite loop spin, finger spin to compete by way of a read lock. Note that, if the queue in the queue the next thread in the non-equity mode is to obtain a write lock, then the spin operation will be broken.

Method for logical tryReleaseShared: infinite loop achieved by for spin, spin logic state is continuously calculates a new value, and then set the new state values ​​compareAndSetState method CAS algorithm.

example

The following is a read-write lock usage example, we instantiate a ReentrantReadWriteLock object, and then to control access to objects of a TreeMap thread safe by its read and write locks. We can see part of the get method to read data operation, so you can use a shared read lock. Put and operate two clear involves changing the data, the need to use an exclusive write lock.

example

to sum up

This article describes the read-write lock ReentrantReadWriteLock Java is, from the point of view to know the name of it has re-entrant nature and provides a read-write lock function. We explain the three elements of its core principles and realization. In ReentrantReadWriteLock read lock, write lock is an exclusive lock, including equity and non-equity mode mode. And it is a shared read-write locks, it also contains a fair and non-equity mode mode. AQS ReentrantReadWriteLock achieve class-based synchronizer, the most important point is to make it through some of the skills to read and write locks the public with a state variable, high 16 and low 16. By explaining this article I believe we have a good grasp of the realization of the principle of read-write locks provided by the JDK.

Focus on artificial intelligence, reading and feelings and talk about mathematics, computer science, distributed, machine learning, deep learning, natural language processing, algorithms and data structures, Java depth, Tomcat kernel and so on.




Guess you like

Origin juejin.im/post/5e5351986fb9a07ca1371252