Reentrantreadwritelock

An implementation of ReadWriteLock supporting similar semantics to ReentrantLock. [1]

The example that follows is from [2]. A set of readers tries to print out an ArrayList represented by data, and a list of Writers tries to add data in to the list.
The try/finally block ensures that the locks are released even in case of runtime errors.

  • Data.java
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.locks.ReentrantReadWriteLock;
 
public class Data
{
    private List<String> names;
 
    ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
 
    public Data()
    {
        names = new ArrayList<String>();
    }
 
    public List<String> getNames()
    {
        return names;
    }
 
    public void setNames(List<String> names)
    {
        this.names = names;
    }
 
    public void add(String str)
    {
        lock.writeLock().lock();
        try {
            System.out.println("Writer: Number of threads waiting : "
                + lock.getQueueLength());
 
            // This will alwas be 1.
            System.out.println("Writer: Number of write locks waiting : "
                + lock.getWriteHoldCount());
            names.add(str);
            try
            {
                Thread.sleep(100);
            } catch (InterruptedException e)
            {
                e.printStackTrace();
            }
        } finally {
            lock.writeLock().unlock();
        }
    }
 
    public void readData()
    {
        lock.readLock().lock();
        try{
            System.out.println("Reader: Number of threads waiting : "
                + lock.getQueueLength());
            System.out.println("Reader: Number of read locks : "
                + lock.getReadLockCount());
            Iterator<String> iter = names.iterator();
            while (iter.hasNext())
            {
                iter.next();
                // System.out.println(iter.next());
            }
            try
            {
                Thread.sleep(100);
            } catch (InterruptedException e)
            {
                e.printStackTrace();
            }
        }finally{
            lock.readLock().unlock();
        }
    }
}
  • ListReader.java
public class ListReader implements Runnable
{
    Data myData;

    public ListReader(Data myData)
    {
        super();
        this.myData = myData;
    }

    public void run()
    {
        for (int i = 0; i < 10; i++)
        {
            myData.readData();
        }
    }
}
  • ListWriter.java
public class ListWriter implements Runnable
{
    Data myData;
 
    public ListWriter(Data myData)
    {
        super();
        this.myData = myData;
    }
 
    public void run()
    {
        for (int i = 0; i < 10; i++)
        {
            myData.add(Thread.currentThread().getName() + " : " + i);
        }
    }
}
  • ReadWriteLockTest.java
package concurrency;
 
public class ReadWriteLockTest
{
    public final static int THREADS = 4;
 
    public static void main(String[] args)
    {
        ListReader[] readers = new ListReader[THREADS];
        ListWriter[] writers = new ListWriter[THREADS];
        Data data = new Data();
        Thread[] threads = new Thread[THREADS * 2];
        for (int i = 0; i < THREADS; i++)
        {
            readers[i] = new ListReader(data);
            writers[i] = new ListWriter(data);
            threads[i] = new Thread(readers[i], "" + i);
            threads[i + THREADS] = new Thread(writers[i], "" + i);
        }
 
        for (int i = 0; i < THREADS * 2; i++)
        {
            threads[i].start();
        }
 
        for (int i = 0; i < THREADS * 2; i++)
        {
            try
            {
                threads[i].join();
            } catch (InterruptedException e)
            {
                e.printStackTrace();
            }
        }
 
    }
}
Bibliography
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-Share Alike 2.5 License.