ReentrantReadWriteLock Lock is a tool that can be used to write a lock on a JAVA server.
Write lock principle
Write lock compared to read lock, logic is relatively simple, let’s take a look at the main logic of write lock and call chain.
There are two main methods:
- TryAcquire:
- If a thread (either itself) holds a read lock or another thread holds a write lock, the current thread calls acquireQueued and waits in the AQS queue.
- If the thread holding the write lock is the current thread, the current thread acquires the write lock and ends (reentrant).
- If a read-write lock is not currently being acquired by any thread, there is a distinction between a fair lock and an unfair lock:
- Fair lock: If a thread is queued in the AQS, the current thread calls acquireQueued to enter the AQS queue
- Unfair lock: The current thread attempts to acquire the write lock, returns if it succeeds, or acquireQueued is called to enter the AQS queue
- acquireQueued
- Try tryAcquire again (in case another thread releases the lock)
- If the lock is successfully obtained, go back
- If not, mark the front node in AQS and tell it to wake me up when you release the lock, then sleep and wait to be woken up
Write lock validation
Here are some examples of read locks:
Case 1: There is currently no thread to read/write the lock
Conclusion: Several threads compete to acquire the lock, and those that fail to acquire the lock enter the AQS queue
/** * get write lock, Are lined up in turn perform * / public static void testWriteLockConcurrently () {ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock(); for (int i = 0; i < 3; i++) { DemoThread thread = new DemoThread("WriteThread" + i, readWriteLock.writeLock()); thread.start(); } } static class DemoThread extends Thread { private DateFormat df = new SimpleDateFormat("HH:mm:ss---"); private Lock lock; public DemoThread(String name, Lock lock) { super(name); this.lock = lock; } @Override public void run() { try { lock.lock(); System.out.println(df.format(new Date()) + getName() + " is working."); Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } finally { System.out.println(df.format(new Date()) + getName() + " finished work."); lock.unlock(); }}}Copy the code
If three threads obtain the write lock at the same time, the three threads obtain the write lock in sequence. The console logs are as follows:
18:02:28---WriteThread0 is working.
18:02:33---WriteThread0 finished work.
18:02:33---WriteThread1 is working.
18:02:38---WriteThread1 finished work.
18:02:38---WriteThread2 is working.
18:02:43---WriteThread2 finished work.
Copy the code
Case 2: The current line gets the read lock first
Conclusion: The current thread is queued to acquire the read lock after it is released
/** * The current line obtains the read lock first, but cannot obtain the write lock again. They only want to be read lock release such as * / public static void testGetWriteLockAfterUnlockReadLockForSameThread () throws the Exception {DateFormat df = new SimpleDateFormat("HH:mm:ss---"); ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock(); ReentrantReadWriteLock.ReadLock readLock = readWriteLock.readLock(); ReentrantReadWriteLock.WriteLock writeLock = readWriteLock.writeLock(); readLock.lock(); System.out.println(df.format(new Date()) + "MainThread got read lock."); Thread.sleep(500); System.out.println(df.format(new Date()) + "MainThread try to get write lock."); writeLock.tryLock(3, TimeUnit.SECONDS); System.out.println( df.format(new Date()) + "Current write lock hold count is:" + readWriteLock.getWriteHoldCount()); readLock.unlock(); }Copy the code
The main thread first obtains the read lock, then attempts to acquire the write lock (timeout: 3 seconds), but never obtains it, and the getWriteHoldCount returns 0
18:11:56---MainThread got read lock.
18:11:57---MainThread try to get write lock.
18:12:00---Current write lock hold count is:0
Copy the code
Case 3: Another thread holds the read or write lock
Conclusion: The current thread is queued to acquire the read lock after it is released
In case 2, the current thread can’t get the unlock immediately, and in case 3, it’s not even possible.
Refer to the article
JAVA concurrency ReentrantLock principle analysis
JAVA Concurrency: ReentrantReadWriteLock
Demo code location
SRC/main/Java/net/weichitech/juc/ReentrantReadWriteLockTest2. Java, small western/Java programming – learning – Gitee.com