Skip to content
On this page

ReadWriteLock

Earlier, we discussed how ReentrantLock ensures that only one thread can execute critical section code at a time:

java
public class Counter {
    private final Lock lock = new ReentrantLock();
    private int[] counts = new int[10];

    public void inc(int index) {
        lock.lock();
        try {
            counts[index] += 1;
        } finally {
            lock.unlock();
        }
    }

    public int[] get() {
        lock.lock();
        try {
            return Arrays.copyOf(counts, counts.length);
        } finally {
            lock.unlock();
        }
    }
}

However, sometimes this kind of protection is excessive. For instance, while it is necessary to acquire the lock for modifying data via the inc() method, the get() method only reads the data without modifying it, meaning multiple threads could safely call it simultaneously.

What we actually want is the ability to allow multiple threads to read at the same time, but when a single thread is writing, all other threads must wait:

OperationReadWrite
ReadYesNo
WriteNoNo

The ReadWriteLock can solve this problem by ensuring:

  • Only one thread can perform a write operation (other threads can neither write nor read).
  • Multiple threads can read simultaneously when no write operation is in progress (improving performance).

Implementing this functionality with ReadWriteLock is straightforward. We create a ReadWriteLock instance and then obtain the read and write locks separately:

java
public class Counter {
    private final ReadWriteLock rwlock = new ReentrantReadWriteLock();
    // Note: The read lock and write lock must be obtained from the same rwlock instance:
    private final Lock rlock = rwlock.readLock();
    private final Lock wlock = rwlock.writeLock();
    private int[] counts = new int[10];

    public void inc(int index) {
        wlock.lock(); // Acquire the write lock
        try {
            counts[index] += 1;
        } finally {
            wlock.unlock(); // Release the write lock
        }
    }

    public int[] get() {
        rlock.lock(); // Acquire the read lock
        try {
            return Arrays.copyOf(counts, counts.length);
        } finally {
            rlock.unlock(); // Release the read lock
        }
    }
}

By using separate read and write locks, multiple threads can acquire the read lock simultaneously during read operations, greatly improving the efficiency of concurrent reads.

ReadWriteLock is suitable when the same data is read frequently by many threads but modified by only a few.

For example, in a forum, posting a reply can be considered a write operation, which is infrequent, while viewing posts can be considered a read operation, which is very frequent. In such cases, ReadWriteLock can be used.

Summary

Using ReadWriteLock can improve read efficiency:

  • ReadWriteLock allows only one thread to perform a write operation.
  • ReadWriteLock allows multiple threads to read simultaneously when there are no write operations.
  • ReadWriteLock is suitable for scenarios with many reads and few writes.
ReadWriteLock has loaded