For this problem we are taking solved examples from some source. Please comment if you find helpful.
/** * * ReaderWriterSolution.java * * This class creates the reader and writer threads and * the database they will be using to coordinate access. */ import java.util.concurrent.Semaphore; public class ReaderWriterSolution{ public static final int NUM_OF_READERS = 3; public static final int NUM_OF_WRITERS = 2; public static void main(String args[]){ RWLock database = new Database(); Thread[] readerArray = new Thread[NUM_OF_READERS]; Thread[] writerArray = new Thread[NUM_OF_WRITERS]; for (int i = 0; i < NUM_OF_READERS; i++) { readerArray[i] = new Thread(new Reader(i, database)); readerArray[i].start(); } for (int i = 0; i < NUM_OF_WRITERS; i++) { writerArray[i] = new Thread(new Writer(i, database)); writerArray[i].start(); } } } //**************************************************************** /** * An interface for reader-writer locks. * * In the text we do not have readers and writers * pass their number into each method. However we do so * here to aid in output messages. */ interface RWLock{ public abstract void acquireReadLock(int readerNum); public abstract void acquireWriteLock(int writerNum); public abstract void releaseReadLock(int readerNum); public abstract void releaseWriteLock(int writerNum); } //**************************************************************** /** * Database.java * * This class contains the methods the readers and writers will use * to coordinate access to the database. Access is coordinated using semaphores. */ class Database implements RWLock{ private int readerCount; // the number of active readers private Semaphore mutex; // controls access to readerCount private Semaphore db; // controls access to the database public Database() { readerCount = 0; mutex = new Semaphore(1); db = new Semaphore(1); } public void acquireReadLock(int readerNum) { try{ //mutual exclusion for readerCount mutex.acquire(); } catch (InterruptedException e) {} ++readerCount; // if I am the first reader tell all others // that the database is being read if (readerCount == 1){ try{ db.acquire(); } catch (InterruptedException e) {} } System.out.println("Reader " + readerNum + " is reading. Reader count = " + readerCount); //mutual exclusion for readerCount mutex.release(); } public void releaseReadLock(int readerNum) { try{ //mutual exclusion for readerCount mutex.acquire(); } catch (InterruptedException e) {} --readerCount; // if I am the last reader tell all others // that the database is no longer being read if (readerCount == 0){ db.release(); } System.out.println("Reader " + readerNum + " is done reading. Reader count = " + readerCount); //mutual exclusion for readerCount mutex.release(); } public void acquireWriteLock(int writerNum) { try{ db.acquire(); } catch (InterruptedException e) {} System.out.println("Writer " + writerNum + " is writing."); } public void releaseWriteLock(int writerNum) { System.out.println("Writer " + writerNum + " is done writing."); db.release(); } } //*********************************************************** /** * Reader.java * * A reader to the database. * */ class Reader implements Runnable { private RWLock database; private int readerNum; public Reader(int readerNum, RWLock database) { this.readerNum = readerNum; this.database = database; } public void run() { while (true) { SleepUtilities.nap(); System.out.println("reader " + readerNum + " wants to read."); database.acquireReadLock(readerNum); // you have access to read from the database // let's read for awhile ..... SleepUtilities.nap(); database.releaseReadLock(readerNum); } } ; } //************************************************************** /** * Writer.java * * A writer to the database. * */ class Writer implements Runnable { private RWLock database; private int writerNum; public Writer(int w, RWLock d) { writerNum = w; database = d; } public void run() { while (true){ SleepUtilities.nap(); System.out.println("writer " + writerNum + " wants to write."); database.acquireWriteLock(writerNum); // you have access to write to the database // write for awhile ... SleepUtilities.nap(); database.releaseWriteLock(writerNum); } } } //***************************************************************** /** * Utilities for causing a thread to sleep. * Note, we should be handling interrupted exceptions * but choose not to do so for code clarity. * */ class SleepUtilities { /** * Nap between zero and NAP_TIME seconds. */ public static void nap() { nap(NAP_TIME); } /** * Nap between zero and duration seconds. */ public static void nap(int duration) { int sleeptime = (int) (NAP_TIME * Math.random() ); try { Thread.sleep(sleeptime*1000); } catch (InterruptedException e) {} } private static final int NAP_TIME = 5; }
No comments:
Post a Comment