Skip to content

Instantly share code, notes, and snippets.

@antgustech
Created January 31, 2017 13:46
Show Gist options
  • Save antgustech/b52fdcd7b2a5e1759086a10dec06fd88 to your computer and use it in GitHub Desktop.
Save antgustech/b52fdcd7b2a5e1759086a10dec06fd88 to your computer and use it in GitHub Desktop.
Assignment 4
package assignment4;
/**
*
* A buffer class that has a 2 arrays, one for strings and one containing
* statuses. One index for each operation. Methods use monitors by using the
* synchronized keyword.
*
*/
public class Buffer {
private final int CAPACITY = 8;
private int addIndex = 0, removeIndex = 0, checkIndex = 0;
private final String[] stringBuffer;
private final STATUS[] statusBuffer;
/**
* Initializes the string buffer with null values and the status buffer with
* EMPTY status.
*
* @param capacity the maximum capacity of the buffers.
*/
public Buffer() {
stringBuffer = new String[CAPACITY];
statusBuffer = new STATUS[CAPACITY];
for (int i = 0; i < CAPACITY; i++) {
stringBuffer[i] = null;
statusBuffer[i] = STATUS.EMPTY;
}
}
/**
* Adds strings to the buffer. Method has a monitor which guarantees mutual
* exclusion. The condition makes sure to block when there is nothing to
* add. We will only add a string when the status for that slot is EMPTY
*
* @param s - String to add.
*/
public synchronized void add(String s) {
addIndex = checkIndex(addIndex);
while (statusBuffer[addIndex] != STATUS.EMPTY) {
try {
System.out.println("Waiting to add Data...");
wait();
} catch (InterruptedException e) {}
}
stringBuffer[addIndex] = s;
statusBuffer[addIndex] = STATUS.NEW;
addIndex++;
notifyAll();
System.out.println("Adding Data '" + s + "'");
}
/**
* Checks the added strings. If the slot we are checking equals the find
* string, we replace that string with the replace string. We wait as long
* as there is nothing new. We will only check a string when the status for
* that slot is NEW
*
* @return true if the string exists.
*/
public synchronized void check(String find, String replace) {
checkIndex = checkIndex(checkIndex);
while (statusBuffer[checkIndex] != STATUS.NEW) {
try {
System.out.println("Waiting to check Data.");
wait();
} catch (InterruptedException e) {}
}
if (stringBuffer[checkIndex].equals(find)) {
stringBuffer[checkIndex] = replace;
System.out.println("Replaced '" + stringBuffer[checkIndex] + "' with '" + replace + "'");
} else
System.out.println("No replacement");
statusBuffer[checkIndex] = STATUS.CHECKED;
checkIndex++;
notifyAll();
}
/**
* Removes strings from the buffer as long as the slot is checked. We will
* only remove a string when the status for that slot is CHECKED
*/
public synchronized String remove() {
removeIndex = checkIndex(removeIndex);
while (statusBuffer[removeIndex] != STATUS.CHECKED) {
try {
System.out.println("Waiting to return Data...");
wait();
} catch (InterruptedException e) {}
}
String s = stringBuffer[removeIndex];
statusBuffer[removeIndex] = STATUS.EMPTY;
removeIndex++;
notifyAll();
System.out.println("Returning Data '" + s + "'");
return s;
}
/**
* Checks if the index is out of bounds.
*
* @param i - int the index to check.
* @return index.
*/
private int checkIndex(int i) {
if (i > CAPACITY - 1) {
i = 0;
}
return i;
}
}
package assignment4;
/**
* Modifier thread that calls on the check method in the buffer.
*
* @author Anton Gustafsson
*
*/
public class Modifier implements Runnable {
private Buffer buffer;
private String find, replace;
public Modifier(Buffer buffer, String find, String replace) {
this.buffer = buffer;
this.find = find;
this.replace = replace;
}
@Override
public void run() {
while (!Thread.interrupted()) {
buffer.check(find, replace);
try {
Thread.sleep((int) (Math.random() * 100));
} catch (InterruptedException e) {
}
}
}
}
package assignment4;
import assignment4.Buffer;
/**
* Reader thread that calls on the buffer to remove elements.
*
* @author Anton Gustafsson
*
*/
public class Reader implements Runnable {
private Buffer buffer;
private Callback cb;
public Reader(Buffer buffer, Callback cb) {
this.buffer = buffer;
this.cb = cb;
}
public void run() {
while (!Thread.interrupted()) {
String s = buffer.remove();
cb.returnData(s + " ");
try {
Thread.sleep((int) (Math.random() * 100));
} catch (InterruptedException e) {
}
}
}
}
package assignment4;
/**
* Enum for statuses.
* @author station
*
*/
public enum STATUS {
EMPTY,NEW,CHECKED;
}
package assignment4;
import assignment4.Buffer;
/**
* Writer thread that turns the string to an array and then adds all those
* elements to the buffer with calls to the buffer's add method.
*
* @author Anton Gustafsson
*
*/
public class Writer implements Runnable {
private Buffer buffer;
private String plain;
public Writer(Buffer buffer, String plain) {
this.buffer = buffer;
this.plain = plain;
}
@Override
public void run() {
String[] a = plain.split(" ");
for (int i = 0; i < a.length && !Thread.interrupted(); i++) {
buffer.add(a[i]);
try {
Thread.sleep((int) (Math.random() * 100));
} catch (InterruptedException e) {
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment