Hallo Leute,
ich stehe vor einem kleinen Problem bei einer kleinen Übungsaufgabe bei der es um Threads geht.
Die Aufgabe sieht ganz grob etwa so aus:
Es soll eine Klasse geben die einen Stack darstellen soll in der int Werte gespeichert werden können, natürlich hat diese die klassischen Methoden pop() und push(int val) also ein LIFO.
Dann soll es zwei klassen geben die den Stack lesen und füllen, diese beiden Klassen sollen Threads sein...
Das Programm soll so ablaufen, dass man einen Stack, Reader und Writer erstellt, dann startet man den Reader und den Writer.
Der Reader soll ununterbrochen laufen!
Der Writer soll 10 Werte schreiben und anschließend ist er fertig und dann soll auch das Programm zu ende gehen!
(Ich habe jetzt die Aufgabe sehr grob beschrieben)
So sehen meine Klassen aus:
(Das grobe Gerüst der Klassen war (leider) gegeben)
So nun zu meinem kleinen Problem...
Im prinzip funktioniert das Programm und tut auch was es soll, doch das Problem ist folgendes:
Die Aufgabe verlangt das wenn eine Zahl in den Stack gelegt wird, der Stack ausgegeben werden soll,
das gleiche soll passieren wenn eine Zahl aus dem Stack genommen wird...
Hier wird nun Mischmasch...
Die Ausgabe kommt mit den Threads nicht hinterher, also zB Writer schreibt eine Zahl rein will dann den Stack ausgeben doch Reader hat die Zahl schon gelesen dh der Stack ist leer usw...
So also kurz gesagt mein Stack ist nicht Thread-Safe...
Doch ich weiß nicht genau wie ich das nun machen soll "synchronized" hilft mir ja auch nicht weiter da ja beide Threads auf unterschiedliche Methoden zugreifen...
Ich hab mir überlegt eine Variable im Stack zu definieren die darstellt ob gerade ein Zugriff auf den Stack erfolgt...
Aber das ist glaube ich nicht der richte Ansatz...
Wie würdet ihr das Problem lösen, natürlich auf guter Java Art
ich stehe vor einem kleinen Problem bei einer kleinen Übungsaufgabe bei der es um Threads geht.
Die Aufgabe sieht ganz grob etwa so aus:
Es soll eine Klasse geben die einen Stack darstellen soll in der int Werte gespeichert werden können, natürlich hat diese die klassischen Methoden pop() und push(int val) also ein LIFO.
Dann soll es zwei klassen geben die den Stack lesen und füllen, diese beiden Klassen sollen Threads sein...
Das Programm soll so ablaufen, dass man einen Stack, Reader und Writer erstellt, dann startet man den Reader und den Writer.
Der Reader soll ununterbrochen laufen!
Der Writer soll 10 Werte schreiben und anschließend ist er fertig und dann soll auch das Programm zu ende gehen!
(Ich habe jetzt die Aufgabe sehr grob beschrieben)
So sehen meine Klassen aus:
(Das grobe Gerüst der Klassen war (leider) gegeben)
Java:
public class Main {
public static void main(String[] args) {
Stack s = new Stack(5);
Thread w = new Writer(s);
Thread r = new Reader(s);
w.start();
r.start();
while (w.isAlive()) {
}
System.exit(0);
}
}
Java:
public class Stack {
private int[] refIntarr;
private int top = 0;
public Stack(int size) {
refIntarr = new int[size];
}
public void print() {
for (int i = 0; i < top; i++) {
System.out.print("[" + refIntarr[i] + "] ");
}
System.out.println();
}
public void push(int val) throws OverflowException {
if (top >= refIntarr.length) {
throw new OverflowException();
} else {
refIntarr[top] = val;
top++;
}
}
public int pop() throws UnderflowException {
if (top <= 0) {
throw new UnderflowException();
} else {
int temp = refIntarr[top - 1];
top--;
return temp;
}
}
}
Java:
import java.util.logging.Level;
import java.util.logging.Logger;
public class Writer extends Thread {
private Stack stackref = null;
public Writer(Stack stackref) {
this.stackref = stackref;
}
@Override
public void run() {
int zahl;
for (int i = 0; i < 10; i++) {
zahl = (int)(Math.random()*10);
try {
stackref.push(zahl);
} catch (OverflowException ex) {
System.out.println("Writer: " + ex.getMessage());
}
System.out.print("Writer ~ print(): ");
stackref.print();
try {
sleep(3);
} catch (InterruptedException ex) {
Logger.getLogger(Writer.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
Java:
import java.util.logging.Level;
import java.util.logging.Logger;
public class Reader extends Thread {
private Stack stackref = null;
public Reader(Stack stackref) {
this.stackref = stackref;
}
@Override
public void run() {
while (true) {
System.out.print("Reader ~ print(): ");
stackref.print();
try {
System.out.println("pop(): " + stackref.pop());
} catch (UnderflowException ex) {
System.out.println("Reader: " + ex.getMessage());
}
try {
sleep(3);
} catch (InterruptedException ex) {
Logger.getLogger(Reader.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
So nun zu meinem kleinen Problem...
Im prinzip funktioniert das Programm und tut auch was es soll, doch das Problem ist folgendes:
Die Aufgabe verlangt das wenn eine Zahl in den Stack gelegt wird, der Stack ausgegeben werden soll,
das gleiche soll passieren wenn eine Zahl aus dem Stack genommen wird...
Hier wird nun Mischmasch...
Die Ausgabe kommt mit den Threads nicht hinterher, also zB Writer schreibt eine Zahl rein will dann den Stack ausgeben doch Reader hat die Zahl schon gelesen dh der Stack ist leer usw...
So also kurz gesagt mein Stack ist nicht Thread-Safe...
Doch ich weiß nicht genau wie ich das nun machen soll "synchronized" hilft mir ja auch nicht weiter da ja beide Threads auf unterschiedliche Methoden zugreifen...
Ich hab mir überlegt eine Variable im Stack zu definieren die darstellt ob gerade ein Zugriff auf den Stack erfolgt...
Aber das ist glaube ich nicht der richte Ansatz...
Wie würdet ihr das Problem lösen, natürlich auf guter Java Art