Shared lock and reentrantreadwritelock of Java concurrency_ Power node Java college sorting

Introduction to readwritelock and reentrantreadwritelock

Readwritelock, as its name suggests, is a read-write lock. It maintains a pair of related locks - "read lock" and "write lock", one for read operation and the other for write operation.

"Read lock" is used for read-only operation. It is a "shared lock" and can be obtained by multiple threads at the same time.

Write lock is used for write operations. It is an exclusive lock. Write locks can only be obtained by one thread lock.

Note: read lock and write lock cannot exist at the same time!

Readwritelock is an interface. Reentrantroadwritelock is its implementation class. Reentrantroadwritelock includes subclasses readlock and writelock.

List of readwritelock and reentrantreadwritelock functions

Readwritelock function list

List of reentrantreadwritelock functions

Reentrantreadwritelock data structure

The UML class diagram of reentrantreadwritelock is as follows:

It can be seen that:

(01) reentrantreadwritelock implements the readwritelock interface. Readwritelock is a read-write lock interface, which provides "readlock() function for obtaining read lock" and "writelock() function for obtaining write lock".

(02) reentrantreadwritelock contains sync object, readerlock for read lock and writerlock for write lock. Both readlock and writelock implement the lock interface. Read lock readlock and write lock writelock also contain "sync objects" respectively. Their sync objects are the same as those of reentrantreadwritelock, that is, access to the same object is realized through sync, read lock and write lock.

(03) like "reentrantlock", sync is of sync type; Moreover, sync is also an abstract class inherited from AQS. Sync also includes fair lock fairsync and non fair lock nonfairsync. The sync object is one of "fairsync" and "nonfairsync". The default is "nonfairsync".

Among them, the codes related to the shared lock source code are as follows:

explain:

Sync in readlock is a sync object. Sync inherits from AQS class, that is, sync is a lock. There is also a sync object in reentrantreadwritelock, and sync in readlock corresponds to sync in reentrantreadwritelock. That is, reentrantreadwritelock and readlock share the same AQS object and the same lock.

The definition of sync in reentrantreadwritelock is as follows:

Next, the shared lock will be described from the two aspects of "obtaining shared lock" and "releasing shared lock".

Get shared lock

The idea of obtaining a shared lock (that is, the step of the lock function) is to try to obtain a shared lock through tryacquiresered(). If the attempt is successful, return directly; If the attempt fails, it will continue to cycle through doacquireshared() and try to acquire the lock. If necessary, it will block the waiting. Doacquireshared() attempts to acquire a lock every time in the loop through tryacquireshared(). Let's take a look at the detailed process of "obtaining shared lock".

1. lock()

Lock() is in readlock. The source code is as follows:

2. acquireShared()

Sync inherits from AQS, and acquireshared() is defined in AQS. The source code is as follows:

Note: acquiresshared() will first try to acquire the lock through tryacquiresshared().

If the attempt is successful, no action will be taken (because the lock has been successfully obtained).

If the attempt fails, the lock is acquired through doacquireshared(). Doacquireshared() returns only after obtaining the lock.

3. tryAcquireShared()

Tryacquireshared() is defined in reentrantreadwritelock Java sync, the source code is as follows:

Description: tryacquireshared() is used to try to obtain "shared lock".

If "no blocking waiting is required" and "the shared count of read lock is less than max_count" when trying to acquire lock, update "the shared count of read lock" directly through CAS function and "the number of times the current thread acquires read lock + 1". Otherwise, the read lock is obtained through fulltryacquisseshared().

4. fullTryAcquireShared()

Fulltryacquireshared() is defined in reentrantreadwritelock. The source code is as follows:

Note: fulltryacquireshared() will process according to "whether blocking waiting is required", "whether the shared count of read lock exceeds the limit", etc. If the blocking wait is not required and the shared count of the lock does not exceed the limit, the CAS attempts to acquire the lock and returns 1.

5. doAcquireShared()

Doacquishared() is defined in the AQS function. The source code is as follows:

Note: doacquireshared() is used to obtain shared locks.

It will first create the node of the CLH queue corresponding to the thread, and then add the node to the CLH queue. A CLH queue is a queue that manages waiting threads that acquire locks. If "current thread" is the header of CLH queue, try to obtain the shared lock; Otherwise, shouldparkafterfailedacquire() should be used to determine whether to block the wait. If necessary, parkandcheckinterrupt() should be used to block the wait.

Doacquireshared() will continue the above operations through the for loop; The purpose is to obtain the shared lock. It should be noted that doacquireshared() is executed through tryacquireshared() every time it tries to acquire a lock!

Release shared lock

The idea of releasing the shared lock is to try to release the shared lock through tryrereleaseshared(). If the attempt is successful, wake up "other threads waiting to obtain the shared lock" through doreaseshared() and return true; Otherwise, it returns flash.

1. unlock()

Note: this function actually calls releaseshared (1) to release the shared lock.

2. releaseShared()

Releaseshared() is implemented in AQS. The source code is as follows:

Note: the purpose of releaseshared() is to let the current thread release the shared lock it holds.

It first attempts to release the shared lock through tryrereleaseshared(). If the attempt is successful, it returns directly; If the attempt fails, release the shared lock through doreleaseshared().

3. tryReleaseShared()

Tryrereleaseshared() is defined in reentrantreadwritelock. The source code is as follows:

Note: tryrereleaseshared() is used to attempt to release the shared lock.

4. doReleaseShared()

Doreleaseshared() is defined in AQS. The source code is as follows:

Note: doreleaseshared() will release the "shared lock". It will traverse the CLH queue from front to back, successively "wake up" and then "execute" the thread corresponding to each node in the queue; The ultimate goal is for these threads to release the locks they hold.

Fair shared lock and unfair shared lock

Like reentrantlock, readlock is also divided into fair lock and unfair lock.

The difference between a fair lock and a non fair lock is that the function readershouldblock() used to determine whether blocking is required is different.

The source code of readershouldblock() of fair lock is as follows:

In the fair shared lock, if there are other threads waiting to obtain the shared lock in front of the current thread, return true; Otherwise, false is returned.

The source code of readershouldblock() of unfair lock is as follows:

In an unfair shared lock, it ignores whether there are other threads in front of the current thread waiting to acquire the shared lock. Returns true as long as the thread corresponding to the unfair shared lock is not null.

Reentrantreadwritelock example

Operation results:

Result description:

(01) observing the running results of thread 0 and thread-2, we found that thread-0 started and obtained the "read lock". When it was not running, thread-2 also started and successfully obtained the "read lock".

Therefore, read lock can be acquired by multiple threads at the same time.

(02) observe the three "write lock" threads: thread-1, thread-3 and thread-5. As long as the "write lock" is obtained by a thread, the thread runs completely before releasing the lock.

Therefore, "write lock" does not support being acquired by multiple threads at the same time.

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>