Search code examples
javamultithreadinglockingreentrantlock

Example demonstrating the use of ReadWriteLock


I am trying to understand the concept of ReadWriteLock and implemented the below simple example. From what I have understood, whenever a thread has a readlock, another thread can acquire the readlock. But for a thread with writelock, no other thread can acquire the write/read lock, until the other thread releases the lock. However from the output of the below program, I noticed that before the WriterOdd release the lock(prints the output of releasing the lock), the Reader threads come in and reads the number String. Is it because just after releasing the writelock the reader threads come in and then the print statement of releasing the writelock is printed?

public static void main(String[] args) {

    new Thread(new Reader(), "Reader 1").start();
    new Thread(new Reader(), "Reader 2").start();
    new Thread(new WriterEven(), "Writer Even").start();
    new Thread(new WriterOdd(), "Writer Odd").start();

}

public static class Reader implements Runnable {

    public void run() {

        for (int i = 1; i <= 6; i++) {
            rwl.readLock().lock();
            // rl.lock();
            System.out.println(Thread.currentThread().getName() + "  is reading" + number);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally {
                rwl.readLock().unlock();
            }
        }

    }

}

public static class WriterEven implements Runnable {

    public void run() {
        System.out.println(Thread.currentThread().getName() + " is trying  writing");
        rwl.writeLock().lock();
        System.out.println(Thread.currentThread().getName() + " got the lock");
        for (int i = 2; i <= 6; i += 2) {

            System.out.println(Thread.currentThread().getName() + " is writing");
            number = number.concat(" " + i);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally {

            }

        }
        rwl.writeLock().unlock();

        System.out.println(Thread.currentThread().getName() + " left the lock");

    }

}

public static class WriterOdd implements Runnable {

    public void run() {
        System.out.println(Thread.currentThread().getName() + " is trying  writing");
        rwl.writeLock().lock();
        System.out.println(Thread.currentThread().getName() + " got the lock");
        for (int i = 1; i <= 5; i += 2) {

            System.out.println(Thread.currentThread().getName() + " is writing");
            number = number.concat(" " + i);
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally {

            }

        }
        rwl.writeLock().unlock();
        System.out.println(Thread.currentThread().getName() + " left the lock");

    }

}

OUTPUT:

Reader 2  is reading0
Reader 1  is reading0
Writer Even is trying  writing
Writer Odd is trying  writing
Writer Even got the lock
Writer Even is writing
Writer Even is writing
Writer Even is writing
Writer Odd got the lock
Writer Odd is writing
Writer Even left the lock
Writer Odd is writing
Writer Odd is writing
Reader 1  is reading0 2 4 6 1 3 5
Reader 2  is reading0 2 4 6 1 3 5
Writer Odd left the lock

Solution

  • Line of code that writes console message about releasing write lock is AFTER releasing the lock.

    rwl.writeLock().unlock();
    // here readers can read already
    // because they are free to aquire lock
    System.out.println(Thread.currentThread().getName() + " left the lock");