The rules for ReentrantReadWriteLock are:

Multithreading: read-write mutual exclusion, writ-read mutual exclusion, writ-write mutual exclusion, read-read sharing

Verify read-write mutex, writ-read Mutex, writ-write Mutex, read-read Share

// Single thread read - read is not mutually exclusive r.lock(); r.lock(); System.out.println(" read-read not mutually exclusive "); r.unlock(); r.unlock(); New Thread(() -> {r.lock(); try {Thread.sleep(2000L); } catch (InterruptedException e) {} r.unlock(); }).start(); new Thread(() -> { r.lock(); System.out.println(" execute immediately "); r.unlock(); }).start(); // Single thread read-write mutually exclusive, no lock upgrade r.lock(); w.lock(); System.out.println("ok"); w.unlock(); r.unlock(); New Thread(() -> {w.lock(); try {Thread.sleep(10000000L); } catch (InterruptedException e) {} w.unlock(); }).start(); try {Thread.sleep(500L); } catch (InterruptedException e) {} New Thread(() -> {r.lock(); System.out.println(" I can get read lock "); r.unlock(); }).start();Copy the code

ReentrantReadWriteLock Usage scenario

For data-sensitive scenarios,

Read lock: It is impossible to read data with multiple inconsistencies. This is a bit like repeatable and phantom reads.

Write lock: Data cannot be written at the same time

private final Map<String, Data> m = new TreeMap<String, Data>(); private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); private final Lock r = rwl.readLock(); private final Lock w = rwl.writeLock(); public Data get(String key) { r.lock(); try { return m.get(key); } finally { r.unlock(); } } public String[] allKeys() { r.lock(); try { return m.keySet().toArray(); } finally { r.unlock(); } } public Data put(String key, Data value) { w.lock(); try { return m.put(key, value); } finally { w.unlock(); } } public void clear() { w.lock(); try { m.clear(); } finally { w.unlock(); }}Copy the code

Lock down

The single-threaded case has a special point: read-write is not mutually exclusive, i.e. degraded

// single thread write - read is not mutually exclusive, degrade w.lock(); r.lock(); System.out.println("ok"); r.unlock(); w.unlock(); // The new Thread(() -> {w.lock(); // The new Thread(() -> {w.lock(); // The new Thread() -> {w.lock(); r.lock(); System.out.println(" I have been demoted "); try {Thread.sleep(2000L); } catch (InterruptedException e) {} r.unlock(); w.unlock(); }).start(); new Thread(() -> { r.lock(); System.out.println(" I can enter "); r.unlock(); }).start(); New Thread(() -> {w.lock(); new Thread(() -> {w.lock(); r.lock(); w.unlock(); System.out.println(" I have been demoted "); try {Thread.sleep(2000L); } catch (InterruptedException e) {} r.unlock(); }).start(); new Thread(() -> { r.lock(); System.out.println(" I can enter "); r.unlock(); }).start();Copy the code

Lock degradation can help us get the result of the current thread’s modification without being corrupted by other threads

Typical use of lock degradation

private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
 private final Lock r = rwl.readLock();
 private final Lock w = rwl.writeLock();

w.lock();
//writing
r.lock();
w.unlock();
//reading
r.unlock();
Copy the code