javaconcurrencyreentrantreadwritelock

ReadWrite locks in Java


While a write lock is being held, Read lock can be acquired. But not vice versa. What is the rationale for this design choice.

  public static void main(String[] args)
    {
        System.out.println("read to write test");
        ReadWriteLock lock = new ReentrantReadWriteLock();
        
        lock.writeLock().lock();
        lock.readLock().lock();
        
        System.out.println("Read locks can be acquired after  Write locks are acquired as well.");
    }

Output of above code:

read to write test
Read locks can be acquired after  Write locks are acquired as well.

Vice versa doesn't work.

public static void main(String[] args) throws InterruptedException {


        ReadWriteLock lock = new ReentrantReadWriteLock();


        lock.readLock().lock();
        
        System.out.println("Read lock is  acquired");
        System.out.print("Trying to get write lock. ");

        boolean  writeLockAcquired =  lock.writeLock().tryLock(120, TimeUnit.SECONDS);
        if (! writeLockAcquired){
            System.out.println("Even after 120 seconds, we  couldn't get write lock");
        }
        else{
            System.out.println("We could get write lock.");
        }
        
    }

Here is the output:

Read lock is  acquired
Trying to get write lock. Even after 120 seconds, we  couldn't get write lock

Can some one point to snippets in Java open source projects to look at practical usage of Read Write locks. I understand that there are a lot of Java open source projects like ElasticSearch / Hadoop / Spark etc.


Solution

  • While a write lock is being held, Read lock can be acquired.

    Locking is to protect against access by concurrent threads.

    A read-write lock allows multiple concurrent readers OR a single writer thread.

    If a thread owns the write lock, it already has exclusive access, so there's no harm in granting it read access. It will not conflict with itself.

    If a thread owns the read lock, there is no guarantee it has exclusive access, so granting the write lock is disallowed. There is no benefit in special-casing the 'single thread wanting both locks' situation.

    In other systems, the lock modes are referred to as 'exclusive' (= write) and 'shared' (= read) modes. Considering those terms might help clarify the situation.

    There is further rationale in the documentation for the reentrant read-write lock:

    Additionally, a writer can acquire the read lock, but not vice-versa. Among other applications, reentrancy can be useful when write locks are held during calls or callbacks to methods that perform reads under read locks. If a reader tries to acquire the write lock it will never succeed.