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:
  1. 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.
  2. If the thread holding the write lock is the current thread, the current thread acquires the write lock and ends (reentrant).
  3. 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:
  4. Fair lock: If a thread is queued in the AQS, the current thread calls acquireQueued to enter the AQS queue
  5. 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
  1. Try tryAcquire again (in case another thread releases the lock)
  2. If the lock is successfully obtained, go back
  3. 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