/*
Software Architecture Design Patterns in Java by Partha Kuchana
Auerbach Publications
*/
public class ReadWriteLockTest {
public static void main(String[] args) { Item item = new Item("CompScience-I"); new MemberTransaction("Member1", item, "StatusCheck"); new MemberTransaction("Member2", item, "StatusCheck"); new MemberTransaction("Member3", item, "CheckOut"); new MemberTransaction("Member4", item, "CheckOut"); new MemberTransaction("Member5", item, "CheckOut"); new MemberTransaction("Member6", item, "StatusCheck");
} }
class Item {
private String name;
private ReadWriteLock rwLock;
private String status;
public Item(String n) { name = n; rwLock = new ReadWriteLock(); status = "N"; }
public void checkOut(String member) { rwLock.getWriteLock(); status = "Y"; System.out.println(member + " has been issued a write lock-ChkOut"); rwLock.done(); }
public String getStatus(String member) { rwLock.getReadLock(); System.out.println(member + " has been issued a read lock"); rwLock.done(); return status; }
public void checkIn(String member) { rwLock.getWriteLock(); status = "N"; System.out.println(member + " has been issued a write lock-ChkIn"); rwLock.done(); } }
class ReadWriteLock {
private Object lockObj;
private int totalReadLocksGiven;
private boolean writeLockIssued;
private int threadsWaitingForWriteLock;
public ReadWriteLock() { lockObj = new Object(); writeLockIssued = false; }
/* * A read lock can be issued if there is no currently issued write lock and * there is no thread(s) currently waiting for the write lock */
public void getReadLock() { synchronized (lockObj) { while ((writeLockIssued) || (threadsWaitingForWriteLock != 0)) { try { lockObj.wait(); } catch (InterruptedException e) { // } } //System.out.println(" Read Lock Issued"); totalReadLocksGiven++; } }
/* * A write lock can be issued if there is no currently issued read or write * lock */
public void getWriteLock() { synchronized (lockObj) { threadsWaitingForWriteLock++;
while ((totalReadLocksGiven != 0) || (writeLockIssued)) { try { lockObj.wait(); } catch (InterruptedException e) { // } } //System.out.println(" Write Lock Issued"); threadsWaitingForWriteLock--; writeLockIssued = true;
} }
//used for releasing locks public void done() { synchronized (lockObj) {
//check for errors if ((totalReadLocksGiven == 0) && (!writeLockIssued)) { System.out.println(" Error: Invalid call to release the lock"); return; } if (writeLockIssued) writeLockIssued = false; else totalReadLocksGiven--;
lockObj.notifyAll(); }
}
}
class MemberTransaction extends Thread {
private String name;
private Item item;
private String operation;
public MemberTransaction(String n, Item i, String p) { name = n; item = i; operation = p; start(); }
public void run() { //all members first read the status item.getStatus(name);
if (operation.equals("CheckOut")) { System.out.println("\n" + name + " is ready to checkout the item."); item.checkOut(name); try { sleep(1); } catch (InterruptedException e) { // } item.checkIn(name); } } }
|