Search code examples
javamultithreadingjava.util.concurrent

reading concurrently but locking with edits


I'm looking for a solution that allows multiple threads to read the shared resource (concurrency permitted) but then locks these reading threads once a thread enters a mutating block, to achieve best of both world.

class Foo {

    Map<String, String> sharedResource;

    public void read() // multiple reading threads allowed, concurrency ok, lock this only if a thread enters the mutating block below.
    {
         // read concurrently unless a thread enters mutating blocks add/remove
    }

    public void add() // this should lock any threads entering this block as well as lock the reading threads above
    {
        synchronized(sharedResource) // lock remove and read
        {
        }
    }

    public void remove() // lock add and read
    {
        synchronized(sharedResource)
        {
        }
    }
}

Is there such a solution in Java?


Solution

  • It's a classic read/write lock scenario:

    class Foo {
    
        Map<String, String> sharedResource;
        ReadWriteLock lock = new ReentrantReadWriteLock();
    
        public void read() {
             lock.readLock().lock();
             try {
                 // read
             } finally {
                 lock.readLock().unlock();
             }
        }
    
        public void add() {
             lock.writeLock().lock();
             try {
                 // add
             } finally {
                 lock.writeLock().unlock();
             }
        }
    
        public void remove() {
             lock.writeLock().lock();
             try {
                 // remove
             } finally {
                 lock.writeLock().unlock();
             }
        }
    }
    

    The read lock can be shared, but the write lock is exclusive to both reads and writes.