ReentrantReadWriteLock ReadWriteLock Java Example - Java @ Desk

Saturday, April 5, 2014

ReentrantReadWriteLock ReadWriteLock Java Example

ReentrantReadWriteLock ReadWriteLock Java Example

java.util.concurrent.locks.ReentrantReadWriteLock and java.util.concurrent.locks.ReadWriteLock are two locking mechanisms in java that helps in getting locks in concurrent applications.

It helps in resolving the concurrency error that may get caused due to multiple reading or writing in a shared resource.

For instance, if multiple threads are reading a shared resource all will get consistent values, but what if multiple threads are writing a value to a particular field that is also being read. In this case, there may be an inconsisteny in reading.

The principal behind ReentrantReadWriteLock is
1) Write Lock - If no threads have locked the ReadWriteLock for reading or writing, this can achieve a lock for writing. At a time, only 1 thread gets a lock of ReadWriteLock for writing. And once a thread achieves a lock for writing, no other thread be it reading or writing will not get a lock and all will wait for this lock to get released

2) Read Lock - If no threads have locked the ReadWriteLock for writing, multiple threads can lock the lock for reading.

Thus, Multiple threads can achieve a Read Lock for reading a data, but only a single thread can achieve a lock for Writing.

Consider a below client application to demonstrate the ReadWriteLocks in java. In this, a small stock price application is explained. Multiple readers can read the stock price while only one Writer can update the stock price and when Writer is updating a stock price all other readers and writers enter into wait state.

For Writer, I have five threads and for Reader, I have 15 threads.

LockPojo.java

package com.readWriteLock;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class LockPojo {

 public LockPojo(ReentrantReadWriteLock readWriteLock) {
  super();
  this.readWriteLock = readWriteLock;
  this.readLock = readWriteLock.readLock();
  this.writeLock = readWriteLock.writeLock();
 }

 private ReadWriteLock readWriteLock;

 private Lock readLock;

 private Lock writeLock;

 private Double lastTradedPrice;

 public ReadWriteLock getReadWriteLock() {
  return readWriteLock;
 }

 public void setReadWriteLock(ReadWriteLock readWriteLock) {
  this.readWriteLock = readWriteLock;
 }

 public Lock getReadLock() {
  return readLock;
 }

 public void setReadLock(Lock readLock) {
  this.readLock = readLock;
 }

 public Double getLastTradedPrice() {
  return lastTradedPrice;
 }

 public void setLastTradedPrice(Double lastTradedPrice) {
  this.lastTradedPrice = lastTradedPrice;
 }

 public Lock getWriteLock() {
  return writeLock;
 }

 public void setWriteLock(Lock writeLock) {
  this.writeLock = writeLock;
 }

}


ReadStockPrice.java



package com.readWriteLock;

import java.text.DecimalFormat;

public class ReadStockPrice implements Runnable {

 @Override
 public void run() {
  System.out.println("Reader Started - " + Thread.currentThread().getName());
  this.getLockPojo().getReadLock().lock();
  try {
   Thread.sleep(100);
   DecimalFormat format = new DecimalFormat("#.##");
   System.out.println("Read Stock Price - "
     + format.format(this.getLockPojo().getLastTradedPrice()));
  } catch (InterruptedException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } finally {
   this.getLockPojo().getReadLock().unlock();
   System.out.println("Reader Finished - " + Thread.currentThread().getName());
  }
 }

 private LockPojo lockPojo;

 public LockPojo getLockPojo() {
  return lockPojo;
 }

 public void setLockPojo(LockPojo lockPojo) {
  this.lockPojo = lockPojo;
 }

}


WriteStockPrice.java

package com.readWriteLock;

import java.text.DecimalFormat;

public class WriteStockPrice implements Runnable {

 @Override
 public void run() {
  System.out.println("Writer Started - "
    + Thread.currentThread().getName());
  this.getLockPojo().getWriteLock().lock();
  try {
   DecimalFormat format = new DecimalFormat("#.##");
   Thread.sleep(10000);
   this.getLockPojo().setLastTradedPrice(
     ((this.getLockPojo().getLastTradedPrice() * 0.01) + this
       .getLockPojo().getLastTradedPrice()));
   System.out.println("Write Stock Price - "
     + format.format(this.getLockPojo().getLastTradedPrice()));
  } catch (InterruptedException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } finally {
   this.getLockPojo().getWriteLock().unlock();
   System.out.println("Writer Finished - "
     + Thread.currentThread().getName());
  }
 }

 private LockPojo lockPojo;

 public LockPojo getLockPojo() {
  return lockPojo;
 }

 public void setLockPojo(LockPojo lockPojo) {
  this.lockPojo = lockPojo;
 }
}


ReadWriteLockTest.java

package com.readWriteLock;

import java.util.concurrent.locks.ReentrantReadWriteLock;

public class ReadWriteLockTest {

 public static void main(String args[]) {
  LockPojo lockPojo = new LockPojo(new ReentrantReadWriteLock());
  Double initPrice = new Double(10);
  ReadStockPrice readers = new ReadStockPrice();
  readers.setLockPojo(lockPojo);
  lockPojo.setLastTradedPrice(initPrice);

  WriteStockPrice writers = new WriteStockPrice();
  writers.setLockPojo(lockPojo);

  Thread[] threads = new Thread[20];
  for (int i = 0; i < 20; i++) {
   if (i % 2 == 0 && i < 10)
    threads[i] = new Thread(writers);
   else
    threads[i] = new Thread(readers);
  }
  for (int i = 0; i < 20; i++) {
   threads[i].start();
  }
 }
}


When you will run the application, till the Writer Thread Number 8 is running, all readers will be in wait mode, after that all readers will run at once

Output

Writer Started - Thread-0
Reader Started - Thread-1
Writer Started - Thread-2
Reader Started - Thread-3
Writer Started - Thread-4
Reader Started - Thread-5
Writer Started - Thread-6
Reader Started - Thread-7
Writer Started - Thread-8
Reader Started - Thread-9
Reader Started - Thread-10
Reader Started - Thread-11
Reader Started - Thread-12
Reader Started - Thread-13
Reader Started - Thread-14
Reader Started - Thread-15
Reader Started - Thread-16
Reader Started - Thread-17
Reader Started - Thread-18
Reader Started - Thread-19
Write Stock Price - 10.1
Writer Finished - Thread-0
Read Stock Price - 10.1
Reader Finished - Thread-1
Write Stock Price - 10.2
Writer Finished - Thread-2
Read Stock Price - 10.2
Reader Finished - Thread-3
Write Stock Price - 10.3
Writer Finished - Thread-4
Read Stock Price - 10.3
Reader Finished - Thread-5
Write Stock Price - 10.41
Writer Finished - Thread-6
Read Stock Price - 10.41
Reader Finished - Thread-7
Write Stock Price - 10.51
Writer Finished - Thread-8
Read Stock Price - 10.51
Reader Finished - Thread-9
Read Stock Price - 10.51
Reader Finished - Thread-10
Read Stock Price - 10.51
Reader Finished - Thread-11
Read Stock Price - 10.51
Reader Finished - Thread-12
Read Stock Price - 10.51
Reader Finished - Thread-13
Read Stock Price - 10.51
Reader Finished - Thread-14
Read Stock Price - 10.51
Reader Finished - Thread-15
Read Stock Price - 10.51
Reader Finished - Thread-16
Read Stock Price - 10.51
Reader Finished - Thread-17
Read Stock Price - 10.51
Reader Finished - Thread-18
Read Stock Price - 10.51
Reader Finished - Thread-19


To download source, click here






No comments:

Post a Comment