I have to:
1) Apply the Observer-Observable pattern to the original code.
2) starting from the original code, I have to suppose that the modification of the array fields (slot machine numbers) should be done in parallel by 3 NumberGenerator threads instead of just one.
My output seems to work fine but I'm wondering if my implemention is good enough or if am I doing something wrong. Could you tell me if my code is good or not?
ORIGINAL CODE:
import java.util.*;
public class SlotMachineApp {
private static final int N = 3;
public static void main(String[] args) {
Numbers numeri = new Numbers(N);
(new NumberGenerator(numeri)).start();
}
}
class NumberGenerator extends Thread {
private Numbers nums;
public NumberGenerator(Numbers numeri) {
nums = numeri;
}
public void run() {
Random r = new Random();
for (int i = 1; i < 25; i++) {
int index = r.nextInt(nums.getNum());
nums.set(index, r.nextInt(5));
nums.print();
try {
sleep((int) (Math.random() * 100));
} catch (InterruptedException e) {
return;
}
}
}
}
class Numbers {
private final int[] items;
public Numbers(int n) {
items = new int[n];
}
public int getNum() {
return items.length;
}
public void set(int index, int x) {
items[index] = x;
}
public void print() {
for (int i = 0; i < items.length; i++) {
System.out.print(items[i] + "\t");
}
System.out.println();
int i = 0;
while (i < items.length - 1 && items[i] == items[i + 1]) {
i++;
}
if (i >= items.length - 1) {
System.out.println("ALL EQUAL!!!!");
}
}
}
OBSERVER-OBSERVABLE IMPLEMENTATION:
Model:
package slot;
import static java.lang.Thread.sleep;
import java.util.Observable;
import java.util.Random;
public class Model extends Observable {
private static final int N = 3;
Numbers numbers = new Numbers(N);
NumberGenerator ng = new NumberGenerator(numbers);
class NumberGenerator extends Thread {
private Numbers nums;
public NumberGenerator(Numbers numbers) {
nums = numbers;
}
public void run() {
Random r = new Random();
for (int i = 1; i < 25; i++) {
int index = r.nextInt(nums.getNum());
nums.set(index, r.nextInt(5));
setChanged();
notifyObservers();
try {
sleep((int) (Math.random() * 100));
} catch (InterruptedException e) {
return;
}
}
}
}
class Numbers {
private final int[] items;
public Numbers(int n) {
items = new int[n];
}
public int getNum() {
return items.length;
}
public void set(int index, int x) {
items[index] = x;
}
public void print() {
for (int i = 0; i < items.length; i++) {
System.out.print(items[i] + "\t");
}
System.out.println();
int i = 0;
while (i < items.length - 1 && items[i] == items[i + 1]) {
i++;
}
if (i >= items.length - 1) {
System.out.println("ALL EQUAL!!!!");
}
}
}
}
View:
package slot;
import java.util.Observable;
import java.util.Observer;
public class View implements Observer {
@Override
public void update(Observable o, Object arg) {
if (o != null && o instanceof Model) {
((Model) o).numbers.print();
}
}
}
Controller:
package slot;
public class Controller {
private Model model;
private View view;
public Controller(Model m, View v){
this.model = m;
this.view =v;
}
}
Main:
package slot;
public class Slot {
public static void main(String[] args) {
Model model = new Model();
View view = new View();
Controller controller = new Controller(model, view);
model.addObserver(view);
model.ng.start();
}
}
MVC is not required I just like to use it for practice! If I did something wrong even in the MVC I would like to know please! I know that my Controller is doing nothing but actually I don't know which method to put inside to let Model and View comunicate since Observer-Observable calls update() from model to view.
Thread - Implementation with 3 NumberGenerator:
import java.util.*;
public class SlotMachineApp {
private static final int N = 3;
public static void main(String[] args) {
Numbers numbers = new Numbers(N);
NumberGenerator ng1 = new NumberGenerator(numbers);
NumberGenerator ng2 = new NumberGenerator(numbers);
NumberGenerator ng3 = new NumberGenerator(numbers);
ng1.start();
ng2.start();
ng3.start();
}
}
class NumberGenerator extends Thread {
private Numbers nums;
public NumberGenerator(Numbers numbers) {
nums = numbers;
}
public void run() {
Random r = new Random();
for (int i = 1; i < 25; i++) {
int index = r.nextInt(nums.getNum());
nums.set(index, r.nextInt(5));
nums.print();
try {
sleep((int) (Math.random() * 100));
} catch (InterruptedException e) {
return;
}
}
}
}
class Numbers {
private final int[] items;
public Numbers(int n) {
items = new int[n];
}
public synchronized int getNum() {
return items.length;
}
public synchronized void set(int index, int x) {
items[index] = x;
}
public synchronized void print() {
for (int i = 0; i < items.length; i++) {
System.out.print(items[i] + "\t");
}
System.out.println();
int i = 0;
while (i < items.length - 1 && items[i] == items[i + 1]) {
i++;
}
if (i >= items.length - 1) {
System.out.println("ALL EQUAL!!!!");
}
}
}
I modified the getNum (), set(), and print() methods by adding the keyword synchronized because I think that in this way each thread can work on its own avoiding race condition.