/*
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);
}
}
}