Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Utilizing the Java Programs below, Recall that to solve a readers/writers proble

ID: 3714261 • Letter: U

Question

Utilizing the Java Programs below,

Recall that to solve a readers/writers problem (Operating Systems), create a multi-thread program to simulate the problem. The following conditions must be satisfied:

1. Any number of readers may simultaneously read the file.

2. Only one writer at a time may write to the file.

3. If a writer is writing to the file, no reader may read it.

Please use semaphore to implement mutual exclusion. Please also create some-sort of GUI Interface to choose between Readers having priority or Writers having priority.

Programs:

Explanation / Answer

Hey, to allow multiple readers and only one writer at a time you can use a ReentrantReadWrite Lock.

So, Interface ReadWriteLock maintains a pair of locks for read and write access. The idea behind read-write locks is that it's usually safe to read mutable(shared) variables concurrently as long as nobody is writing to this variable. So the read-lock can be held simultaneously by multiple threads as long as no threads hold the write-lock.

What you have tried to do in process2 class with the help of Semaphores, it would create multiple process2 objects and each object will have it's own copy of Semaphore, hence there would be no meaning of using semaphores. What we want to acheive is a that "the data of one object is shared between multiple threads which are trying to update and read at the same time", I have used a Map to acheive this below..

######################### With MAP ###################################

FileContainer.java

import java.io.FileNotFoundException;

import java.io.IOException;

import java.util.HashMap;

import java.util.Map;

import java.util.concurrent.locks.ReadWriteLock;

import java.util.concurrent.locks.ReentrantReadWriteLock;

public class FileContainer implements Runnable {

private ReadWriteLock lock;

private Map<String, String> map; // reading and writing in a MAP.. which is shared across threads...

public FileContainer() throws IOException, FileNotFoundException {

lock = new ReentrantReadWriteLock(true);

map = new HashMap<>();

}

public void writeFile() throws InterruptedException, IOException {

lock.writeLock().lock();

try {

System.out.println("writing... ");

map.put("I am key", "I am value");

Thread.sleep(10000); // until and unless write lock is released, all the threads waiting on read lock will not be able to proceed..

} finally {

lock.writeLock().unlock();

}

}

public void readFile() throws InterruptedException, IOException {

lock.readLock().lock();

try {

System.out.println("Reading from file... ");

System.out.println(map.get("I am key"));

Thread.sleep(10000);

} finally {

lock.readLock().unlock();

}

}

@Override

public void run() {

if (Thread.currentThread().getName().equals("Reader")) {

try {

readFile();

} catch (InterruptedException | IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

} else {

try {

writeFile();

} catch (InterruptedException | IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

}

App.java

import java.io.FileNotFoundException;

import java.io.IOException;

public class App {

public static void main(String[] args) throws FileNotFoundException, IOException {

FileContainer fileContainer = new FileContainer();

Thread t1 = new Thread(fileContainer);

Thread t2 = new Thread(fileContainer);

Thread t3 = new Thread(fileContainer);

Thread t4 = new Thread(fileContainer);

Thread t5 = new Thread(fileContainer);

t1.setName("Writer");

t2.setName("Reader");

t3.setName("Reader");

t4.setName("Reader");

t5.setName("Reader");

t1.start();

t2.start();

t3.start();

t4.start();

t5.start();

}

}

######################### With File ###################################

import java.io.BufferedReader;

import java.io.BufferedWriter;

import java.io.File;

import java.io.FileNotFoundException;

import java.io.FileReader;

import java.io.FileWriter;

import java.io.IOException;

import java.util.concurrent.locks.ReadWriteLock;

import java.util.concurrent.locks.ReentrantReadWriteLock;

public class FileContainer implements Runnable {

private ReadWriteLock lock;

private static File file = new File("abc.txt"); // Reading and Writing in a file which is shared across threads

public FileContainer() throws IOException, FileNotFoundException {

lock = new ReentrantReadWriteLock(true);

}

public void writeFile() throws InterruptedException, IOException {

lock.writeLock().lock();

try (BufferedWriter bw = new BufferedWriter(new FileWriter(file, true))) {

System.out.println("writing... ");

bw.write("line1 ");

bw.write("line2 ");

bw.write("line3 ");

Thread.sleep(10000); // until and unless write lock is released, all the threads waiting on read lock

} finally {

lock.writeLock().unlock();

}

}

public void readFile() throws InterruptedException, IOException {

lock.readLock().lock();

try (BufferedReader br = new BufferedReader(new FileReader(file))) {

System.out.println("Reading from file... ");

String line = "";

while ((line = br.readLine()) != null) {

System.out.println(line + "Thread Name: " + Thread.currentThread().getName());

}

Thread.sleep(10000);

} finally {

lock.readLock().unlock();

}

}

@Override

public void run() {

if (Thread.currentThread().getName().startsWith("Reader")) {

try {

readFile();

} catch (InterruptedException | IOException e) {

e.printStackTrace();

}

} else {

try {

writeFile();

} catch (InterruptedException | IOException e) {

e.printStackTrace();

}

}

}

}

import java.io.FileNotFoundException;

import java.io.IOException;

public class App {

public static void main(String[] args) throws FileNotFoundException, IOException {

FileContainer container = new FileContainer();

Thread t1 = new Thread(container);

Thread t2 = new Thread(container);

Thread t3 = new Thread(container);

Thread t4 = new Thread(container);

Thread t5 = new Thread(container);

t1.setName("Writer");

t2.setName("Reader1");

t3.setName("Writer");

t4.setName("Reader3");

t5.setName("Reader4");

t4.start();

t5.start();

t1.start();

t2.start();

t3.start();

}

}

############################# Write Priority Class ####################################

import java.io.BufferedReader;

import java.io.BufferedWriter;

import java.io.File;

import java.io.FileReader;

import java.io.FileWriter;

import java.io.IOException;

public class WritePriority implements Runnable {

private int readers = 0;

private int writers = 0;

private volatile boolean isReading = false;

private static File file = new File("abc.txt"); // Reading and Writing in a file which is shared across threads

public synchronized void lockRead() throws InterruptedException {

while (writers > 0) {

wait();

}

isReading = true;

readers++;

}

public synchronized void unlockRead() {

readers--;

isReading = false;

notifyAll();

}

public synchronized void lockWrite() throws InterruptedException {

if (isReading) {

wait();

}

while (writers > 0) {

wait();

}

if (isReading) {

wait();

}

writers++;

}

public synchronized void unlockWrite() throws InterruptedException {

writers--;

notifyAll();

}

public void writeFile() throws InterruptedException, IOException {

lockWrite();

try (BufferedWriter bw = new BufferedWriter(new FileWriter(file, true))) {

System.out.println("writing... ");

bw.write("line1 ");

bw.write("line2 ");

bw.write("line3 ");

Thread.sleep(5000); // until and unless write lock is released, all the threads waiting on read lock

} finally {

unlockWrite();

}

}

public void readFile() throws InterruptedException, IOException {

lockRead();

try (BufferedReader br = new BufferedReader(new FileReader(file))) {

System.out.println("Reading from file... ");

String line = "";

while ((line = br.readLine()) != null) {

System.out.println(line + "Thread Name: " + Thread.currentThread().getName());

}

Thread.sleep(5000);

} finally {

unlockRead();

}

}

@Override

public void run() {

if (Thread.currentThread().getName().startsWith("Reader")) {

try {

readFile();

} catch (InterruptedException | IOException e) {

e.printStackTrace();

}

} else {

try {

writeFile();

} catch (InterruptedException | IOException e) {

e.printStackTrace();

}

}

}

}

import java.io.FileNotFoundException;

import java.io.IOException;

public class App {

public static void main(String[] args) throws FileNotFoundException, IOException {

WritePriority container = new WritePriority();

Thread t1 = new Thread(container);

Thread t2 = new Thread(container);

Thread t3 = new Thread(container);

Thread t4 = new Thread(container);

Thread t5 = new Thread(container);

t1.setName("Writer");

t2.setName("Reader1");

t3.setName("Writer");

t4.setName("Reader3");

t5.setName("Reader4");

t1.start();

t4.start();

t5.start();

t2.start();

t3.start();

}

}

############################### Read Priority Class ###################################

import java.io.BufferedReader;

import java.io.BufferedWriter;

import java.io.File;

import java.io.FileReader;

import java.io.FileWriter;

import java.io.IOException;

public class ReadPriority implements Runnable {

private int readers = 0;

private int writers = 0;

private volatile boolean isWriting = false;

private static File file = new File("abc.txt"); // Reading and Writing in a file which is shared across threads

public synchronized void lockRead() throws InterruptedException {

if (isWriting) {

wait();

}

while (readers > 0) {

wait();

}

if (isWriting) {

wait();

}

readers++;

}

public synchronized void unlockRead() {

readers--;

notifyAll();

}

public synchronized void lockWrite() throws InterruptedException {

while (readers > 0) {

wait();

}

isWriting = true;

writers++;

}

public synchronized void unlockWrite() throws InterruptedException {

writers--;

isWriting = false;

notifyAll();

}

public void writeFile() throws InterruptedException, IOException {

lockWrite();

try (BufferedWriter bw = new BufferedWriter(new FileWriter(file, true))) {

System.out.println("writing... ");

bw.write("line1 ");

bw.write("line2 ");

bw.write("line3 ");

Thread.sleep(5000); // until and unless write lock is released, all the threads waiting on read lock

// will continue waiting.,.

} finally {

unlockWrite();

}

}

public void readFile() throws InterruptedException, IOException {

lockRead();

try (BufferedReader br = new BufferedReader(new FileReader(file))) {

System.out.println("Reading from file... ");

String line = "";

while ((line = br.readLine()) != null) {

System.out.println(line + "Thread Name: " + Thread.currentThread().getName());

}

Thread.sleep(5000);

} finally {

unlockRead();

}

}

@Override

public void run() {

if (Thread.currentThread().getName().startsWith("Reader")) {

try {

readFile();

} catch (InterruptedException | IOException e) {

e.printStackTrace();

}

} else {

try {

writeFile();

} catch (InterruptedException | IOException e) {

e.printStackTrace();

}

}

}

}

import java.io.FileNotFoundException;

import java.io.IOException;

public class App {

public static void main(String[] args) throws FileNotFoundException, IOException {

ReadPriority container = new ReadPriority();

Thread t1 = new Thread(container);

Thread t2 = new Thread(container);

Thread t3 = new Thread(container);

Thread t4 = new Thread(container);

Thread t5 = new Thread(container);

t1.setName("Writer");

t2.setName("Reader1");

t3.setName("Writer");

t4.setName("Reader3");

t5.setName("Reader4");

t4.start();

t1.start();

t5.start();

t2.start();

t3.start();

}

}