Threads und Observer

Status
Nicht offen für weitere Antworten.

vsk

Aktives Mitglied
Hallo, ich habe so meine Probleme mehrere Threads (MVC ähnlich) und das Observer-Pattern zu verheiraten.

Am Ende sollen es 3 Threads sein
Controller Thread
View Thread
Model Thread

Das aktuelle Problem ist, dass ich es nicht schaffe den View Threads mittels Observer update zu aktuallisieren. Im ControllerThread wird eine Tastatureingabe Abgefragt und in Abhängigkeit von der Eingabe soll die View entsprechend aktuallisiert werden.

Meine Main
Java:
public class Main {
    public static void main(String[] args) {
        ControllerKlasse myController = new ControllerKlasse();
        Thread s = new Thread(myController);
        s.start();
    }
}

ControllerKlasse
Java:
import java.util.Observer;
import java.util.Observable;

public class ControllerKlasse extends Observable implements Runnable{
    ViewKlasse myView = new ViewKlasse();
   // @Override
    public void run(){
        myView.start(); //View Thread starten
        this.MenueController();
    }
    /**
     * Methode zur Auswertung der Benutzereingabe
     */
    public void MenueController(){
        System.out.println("MenueController");
        int menueNr = StdInput.readInt();
        System.out.println("gelesen in MenueController: " + menueNr);
        if (menueNr < 1 || menueNr > 6) {		// if-Anweisung zur Pr�fung richtiger Programmpunkt
			System.out.println("Auswahl: " + menueNr + " unbekannt!");
			System.out.println("\nTreffen Sie eine neue Wahl");

		} else {
			switch (menueNr) {
			case 1: //die Anderen Cases fehlen im Moment
                            System.out.println("Case 1");
                            setChanged();
                            //myView.notify();
                            notifyObservers(menueNr);
                            System.out.println("Case 1 durchlaufen");
				break;
			default:
			}//switch
                }//else
    }
}

ViewKlasse
Java:
import java.util.Observer;
import java.util.Observable;

public class ViewKlasse extends Thread implements Observer{

    @Override //wir Ueberschreiben die run() Methode von java.lang.Thread
    public void run(){
        this.Menue();
        try{
            while(true){
             //läuft im Moment "ewig"           
        }
        }catch (Exception e){};
        
    }

    /**
     * Methode Menue() zeigt das textbasierte Auswahlmenue auf der Konsole an
     */
    public void Menue(){
        //ein Auswahlmenue wird angezeigt
    }

    public void update(Observable obs, Object o){ //nur Testausgaben
        System.out.println("hallo ich bin die update");
        int eingabe = (Integer)o;
        System.out.println("Die Eingabe war: " +eingabe);
    }
}
 

javimka

Top Contributor
Du musst dem Observable (Controller) noch den Observer (View) adden. Wahrscheinlich machst du das am besten im Konstruktor des Controllers mit [c]myView.addObserver(this);[/c]

3 Threads für MVC tönt zwar sehr spannend, gehört habe ich davon aber noch nie etwas. Zumindest bei Swing läuft ja ziemlich alles über den Event-Dispatching-Thread. Oder verwendest du AWT oder SWT oder sonst etwas?
 

vsk

Aktives Mitglied
Hallo!
Danke fuer die schnelle Antwort.

Die 3 Threads sind eine Vorgabe. Später soll es mittels Pipes zu einem Datenaustausch zwischen den Threads kommen. Das funktioniert auch soweit.

Ich habe versucht den Controller an die View zu adden. Das funktioniert leider nicht.
Ich benutze als IDE Netbeans und bekomme die Funtion "addObserver" erst garnicht angeboten.

Ich habe mit schon gedacht, dass es daran liegt. In den Beispielen ohne Threads wird die View auch als new Observer Object erzeugt. Dann läuft es aber bei mir nicht als Thread :(
 
Zuletzt bearbeitet:

javimka

Top Contributor
Sorry, ich hatte die beiden Objekte vertauscht, es ist natürlich gerade umgekehrt: [c]this.addObserver(myView);[/c]. Richtig beschrieben, aber falscher Befehl ;)

Es ist allerdings so, dass jener Thread, der im Observable notifyObservers ausführt auch alle update() der Observer ausführt. Wie du das verhindern kannst, wüsste ich jetzt auch nicht direkt, weil du kannst ja nicht wirklich einem Thread einen Befehl geben, wie du es einem Objekt kannst. Du kannst einem Thread nicht sagen, er soll jetzt ein Objekt updaten. Der Thread könnte höchstens durch ein wait() warten bis irgendein anderer Thread notify() aufruft und den Thread damit aufweckt, welcher dann ein update vollzieht.
 

vsk

Aktives Mitglied
Danke!
Hätte ich ja vielleicht auch merken können. Habe aber so das Gefühl ich sitze schon wieder zu lange davor und habe nen "Tunnelblick"

Leider erhalte ich immer noch keine Ausgabe von der Update Methode aus dem View-Thread. Es scheint als würde die Methode garnicht aufgerufen. Ich versteh das nicht, eigentlich unterscheidet sich mein Programm von den Beispielen doch nur im Falle der Threads und dass ich die Objecte nicht alle in der Main erzeuge.

Ich hatte eigentlich vor, das mit wait() und notify() zu regeln. Das führt allerdings dann zu
Exception in thread "Thread-1" java.lang.IllegalMonitorStateException

an der Stelle im Controller Thread an dem ich "myView.notify()" aufrufe.

Edit:
Man sollte sich einfach die Exceptions immer ausgeben lassen...

Ich erhalte den Fehler
java.lang.IllegalMonitorStateException
bereits in der Methode run() von myView
Java:
public class ViewKlasse extends Thread implements Observer{

    @Override //wir Ueberschreiben die run() Methode von java.lang.Thread
    public void run(){
        this.Menue();
        try{
            while(true){
                this.wait(); //<<< hier kommt wohl der Fehler her
                System.out.println("Habe gewartet");
        }
        }catch (Exception e){System.out.println("Error "+e);}   
    }
 
Zuletzt bearbeitet:

javimka

Top Contributor
Wenn du den Observer dem Observable angehängt hast, müsste das funktionieren. Du kannst ja mal countObservers() auf dem Observable aufrufen und schauen, wieviele Observer du hast. Müsste wohl 1 sein, deine myView.

Um ein wait() auf einem Objekt aufrufen zu können muss es in einem synchronized Block liegen. Weil du bei dir das this synchonisierst, kannst du am einfachsten die ganze Methode run() synchronisieren, du schreibst dann einfach: [c]public synchronized void run() { ... [/c].

//EDIT: ein while(true) darum zu legen ist natürlich nicht gerade genial, weil der Thread dann ewig wartet. Du musst true halt durch einen boolean ersetzen, welcher dann zuerst auf false gesetzt wird bevor du this.notify() aufrufst.
 

vsk

Aktives Mitglied
So, die update Methode in myView (ViewKlasse) reagiert nun.

Danke dem Vorschlag mit countObservers() habe ich bemerkt das der Observer nicht hinzugefügt wurde. Aus irgend einem Grund klappt dies im Konstruktor von ControllerKlasse nicht.
Ich habes es jetzt in die run() Methode von ControllerKlasse aufgenommen.
Java:
public class ControllerKlasse extends Observable implements Runnable{
    ViewKlasse myView = new ViewKlasse();
    public void ControllerKlasse(){
//empty
    }
    // @Override
    public void run(){
        this.addObserver(myView);
        myView.start();
        this.MenueController();
    }
...

Jetzt gilt es heraus zu finden warum wait() auch ohne Endlosscheife einen Fehler wirft.
Werde mich später wieder melden...
 

vsk

Aktives Mitglied
wie oben geschrieben: synchronized

wait() funktioniert in der synchronizied run() methode. Aber notify() wirft auch innerhalb eines synchronized(this) bzw in einer synchronized Methode einen Fehler.

Schaue ich mir das Ganze nochmal an kommen mir so meine Zweifel ob es überhautp sinvoll ist.

Denn eigentlich verlege ich ja nur die Abfrage der Benutzereingabe in den Controller Thread, nur um dann in der update() Methode des ViewThreads wieder die Eingabe zu prüfen und dann entsprechend eine Methode der View auf zu rufen... Da kann ich doch gleich aus dem Controller heraus myViewMethode() aufrufen, oder? Wozu hab soll ich dann Threads verwenden?!
 

javimka

Top Contributor
Welche eine Exception wirft das notify denn?

Ich bin auch eher skeptisch, ob all deine Threads wirklich Vorteile bringen. Zumindest für den Unterhalt der Software scheint es einige Komplikationen zu geben, die du sonst nicht hättest. Soweit ich weiss (und wahnsinn viel weiss ich zugegebenermassen nicht) läuft das MVC Pattern in der Regel nur mit einem Thread. Jedenfalls bei den Tutorials, die man so findet.
 

vsk

Aktives Mitglied
Immer noch
java.lang.IllegalMonitorStateException


Das Ganze soll eine Übung sein, um unter anderem mit Pipes zwischen den Threads Daten aus zu tauschen. Ein ModelThread liest aus einer Datei und schickt diese Daten dann an den ViewThread, kontrolliert und koordiniert vom ControllerThread. (Zumindest wenn ich es richtig verstanden habe)
 

javimka

Top Contributor
Kann es sein dass du notify auf einem falschen Objekt aufrufst? Ein Objekt, das nicht synchronized ist. Auch wenn deine Methode synchronized ist, gilt das nicht für die Objekte die du in dieser Methode verwendest. Bei dem wait, da hast du ja wait() auf dem this-Objekt aufgerufen, deshalb konntest du einfach die Methode synchronized machen und das galt dann automatisch für das this Objekt. Wenn du nun notify von einer anderen Klasse her aufrufst, musst du die Referenz auf die ViewKlasse synchronized machen: synchronized(myView) { ... myView.notify() ... }
 

Dissi

Aktives Mitglied
Ohne das mir genau angeschaut zu haben, stach mir eins ins Auge. Ist der Sinn nicht, View kennt Controller -> Controller kennt Model --> Views melden sich über Controller als Observer am Model an. Wieso instanzierst du eine View im Controller? Die Change Propagation läuft über Observer und nicht über der Controller.
 

vsk

Aktives Mitglied
@Dissi

ja... irgendwie ist das alles ein wenig aus dem Ruder gelaufen...
ich hab jetzt viele schönen methoden in meinem Controller welche die updateMethode der View nutzen und der ist es ganz egal in welchem Zustand der ViewThread ist...
Zudem reagiert der ViewThread nach start() auf keine weiteren Befehle wie wait() oder interrupted()...

Wenn ich dich richtig verstehe, müssten eigentlich alle meine Methoden aus dem Controller welche etwas mit der View zu tun haben, in einen ModelThread?

Die Aufgabenstellung war eigentlich...
1.Ein Thread kümmert sich um die Kommunikation mit dem
User („View“-Thread; User Interface).
2. Ein zweiter Thread kümmert sich um die Lese- und
Schreibvorgänge auf der Datenbasis („Model“-Thread).
3. Daten werden in einer CSV Datei gespeichert.
4. Der Datenaustausch und Kommunikation der beiden
Threads erfolgt mit Hilfe einer Pipe.
5. Der Hauptthread ist der „Controler“-Thread.

Ich wollte die Pipe eigentlich nur nehmen um die Daten zum Schreiben an das Model zu schicken...
 
Zuletzt bearbeitet:

javimka

Top Contributor
Wenn du mit Swing arbeitest, wird er Event-Dispatching-Thread (EDT) gestartet, der das Zeichnen übernimmt. Der EDT (und nur der) sind eigentlich für die View zuständig. Es ist durchaus sinnvoll, wenn ein anderer Thread am Modell etwas ändert und dann die Observer verständigt, möglicherweise auch den Controller, der dann die view neu zeichnen lässt.
Ich gehe mit Diss nicht ganz einig, dass das View den Kontroller kennt. Meiner Meinung nach kennt die View das Modell und kann sich gemäss den Daten dort updaten. Der Kontroller kennt die View und das Model und er registriert Listener bei der View, die dann bei User-Interaktionen das Model verändern. Wenn jetzt noch ein anderer Thread am Model rumwerkelt, dann sehe ich im Grunde genommen zwei Varianten, wie das Model dem View befehlen kann, sich neu zu zeichnen.
1. das Model hat eine Methode notifyObserversInEDT() und führt dort folgendes aus:
Java:
SwingUtilities.invakeLater(new Runnable() {
  public void run() { // wird vom EDT ausgeführt
    ViewKlasse.this.notifyObservers();
  }
}
Dadurch kriegt der EDT (View Thread) den Befehl, die Observer (View) zu notifizieren.

2. Du lässt das Model, wie es ist und überschreibst dann in Observer (View) update und delegierst dort die Arbeit an den EDT. Weiss halt nicht, wie genau du das da gemacht hast, vielleicht reicht ein repaint(), welches ja auch vom EDT ausgeführt würde oder du musst es mit SwingUtilities.invokeLater machen.
 

vsk

Aktives Mitglied
Nun mit einer GUI hätte ich das ganze vielleicht leichter verstanden.
Aber die View ist im Moment einfach nur die Konsole... Das heisst der ViewThread ist im Grunde nur für die Ausgabe von Text auf der Konsole zuständig.
Dafür habe ich Methoden im Controller entworfen (die wohl in den ModelThread gehören) welche die kompletten String-Ausgaben (mehrzeilig) zustammenstellen und dann an die View senden, im Moment noch über Observer update() Methode.
Baue jetzt das ganze um, auf Pipe. Wobei mir das irgendwie altmodisch vorkommt. Schließlich muss ich jetzt immer ein Steuerzeichen senden, damit die View weiss wofür der Rest der Daten ist der durch die Pipe kommt...
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
rode45e Java Threads Allgemeine Java-Themen 4
M Threads Allgemeine Java-Themen 1
L Threads Threads in Chatroom Allgemeine Java-Themen 30
berserkerdq2 run-methode eines Threads so programmieren, dass 30x die Sekunde etwas ausgeführt wird. Allgemeine Java-Themen 44
berserkerdq2 Threads, wie genau läuft das in Java ab? (Ich kann Threads erstellen und nutzen, nur das Verständnis) Allgemeine Java-Themen 6
CptK Backpropagation parallelisieren: Kommunikation zwischen den Threads Allgemeine Java-Themen 7
J Eine Frage zu den Threads und Task Allgemeine Java-Themen 1
W Wieviele Threads sind sinnvoll? Allgemeine Java-Themen 8
W Alternative für Threads Allgemeine Java-Themen 6
V Threads Probleme beim Aufrufen von Methoden einer anderen Klasse (Threads) Allgemeine Java-Themen 14
T Multithreading: Wie viele Threads sollte ich erstellen? Allgemeine Java-Themen 12
G Threads vom Mainprogramm steuern Allgemeine Java-Themen 8
S BlockingQueue mit dynamischer Anpassung der Anzahl von Producer und Consumer Threads Allgemeine Java-Themen 1
x46 Threads Threads anhalten Allgemeine Java-Themen 1
J Threads verbessern die Performance NICHT ? Allgemeine Java-Themen 8
W Threads Problem Allgemeine Java-Themen 15
T Threads Tic Tac Toe mit Threads Allgemeine Java-Themen 1
M Threads über Kommandozeile Allgemeine Java-Themen 5
mrbig2017 Threads Chat Programm mit Threads? Allgemeine Java-Themen 2
J Threads - java.lang.IllegalThreadStateException Allgemeine Java-Themen 6
J Internet Broswer in Threads öffnen Allgemeine Java-Themen 1
B Threads Multithreading Threads sollen warten Allgemeine Java-Themen 12
N 1000 MQTT Messages die Sekunde - 1000 Threads erstellen ? Allgemeine Java-Themen 10
D Threads Parallel laufende Threads Allgemeine Java-Themen 4
J Unvorhersehbares Verhalten - benutze ich die falsche Bedingungsprüfung oder brauche ich Threads? Allgemeine Java-Themen 12
D Eine Forschleife mit Threads abarbeiten um es zu schneller zu machen. Ist das möglich? Allgemeine Java-Themen 20
S Wie kann ich eine kleine Stelle in meinem Code mit multiplen Threads abarbeiten..? Allgemeine Java-Themen 20
P Threads Parallelisierte DB-Abfragen mit variabler Anzahl an Threads Allgemeine Java-Themen 4
J Threads Threads Allgemeine Java-Themen 9
Viktim Threads Liste In unterschiedlichen Threads bearbeiten Allgemeine Java-Themen 23
E Threads Ausführung in Threads ist langsamer als ohne Threads Allgemeine Java-Themen 13
A Anzahl an Threads Systemweit Allgemeine Java-Themen 2
Tausendsassa Input/Output Problem mit der gleichzeitigen Ausgabe zweier Threads Allgemeine Java-Themen 8
S Alle Methodenaufrufe eines Threads notieren..? Allgemeine Java-Themen 7
M Threads JPanel eingeforen mit Threads Allgemeine Java-Themen 2
F Threads Allgemeine Java-Themen 6
F Threads Allgemeine Java-Themen 2
M Sinn von Threads? Allgemeine Java-Themen 1
J Wie erschaffe ich einen sicheren Datenaustausch zwischen Thread und Nicht-Threads Allgemeine Java-Themen 8
L Abfragen ob Threads fertig Allgemeine Java-Themen 3
P Threads Java Zugreifen Allgemeine Java-Themen 6
K Problem: Java-Klasse mit mehreren Threads als eigenen Prozess starten Allgemeine Java-Themen 3
K KeyEvent in Threads Allgemeine Java-Themen 11
V Threads Weshalb funktionieren meine Threads nicht? Allgemeine Java-Themen 2
Thallius Speicherverhalten von Properties und mehreren Threads Allgemeine Java-Themen 5
L Threads beenden Allgemeine Java-Themen 4
P Threads Threads nicht gleichzeitig starten Allgemeine Java-Themen 3
S Threads Threads werden nicht beendet Allgemeine Java-Themen 2
S Start des zweiten Threads erst nach Beenden des ersten Threads Allgemeine Java-Themen 13
N Threads statische Methoden in Threads Allgemeine Java-Themen 5
P 4 Threads in einer Methode Allgemeine Java-Themen 2
M Eclipse Mehrere Threads, mehrere Konsolen Allgemeine Java-Themen 4
OnDemand Threads und synchronized Allgemeine Java-Themen 9
R LinkedList und Threads: Strukturprobleme bez. löschen von Elementen Allgemeine Java-Themen 3
R LinkedList und Threads - welche Methode ist besser? Allgemeine Java-Themen 2
OnDemand Threads und synvhronized Allgemeine Java-Themen 2
S Problem mit Threads Allgemeine Java-Themen 1
W Threads Threads warten lassen Allgemeine Java-Themen 5
H Optimierung durch Threads Allgemeine Java-Themen 31
B Threads halten sich irgendwie auf... Allgemeine Java-Themen 6
M Threads Allgemeine Java-Themen 8
K JNI: Methoden aus unterschiedlichen Threads aufrufen Allgemeine Java-Themen 3
A Applet Alle Threads beim schließen des Applets beenden Allgemeine Java-Themen 8
A Problem mit der Synchronisierung von Threads Allgemeine Java-Themen 15
R SecurityManager für einzelne Klassen/Threads? Allgemeine Java-Themen 38
O Threads und If Befehle Allgemeine Java-Themen 7
P Threads abwechseln lassen mit wait() und notify() Allgemeine Java-Themen 2
H Sehr viele Threads effizient Verwalten Allgemeine Java-Themen 13
C Threads und Exceptions Allgemeine Java-Themen 7
H java.lang.OutOfMemoryError bei der wiederholten Erzeugng von Threads Allgemeine Java-Themen 8
S Threads Abarbeitungsstatus von Threads in Datei schreiben Allgemeine Java-Themen 2
M Zugriff zweier Threads auf diesselbe Methode Allgemeine Java-Themen 16
E Threads Sudoku Threads Allgemeine Java-Themen 8
M Java Threads - Wait Notify - Verständnisproblem Allgemeine Java-Themen 5
Gossi Threads mit unterschiedlichen Aufgaben in einer Klasse? Allgemeine Java-Themen 9
G Threads Ablauf von Threads im Spezialfall Allgemeine Java-Themen 4
V Threads bei quadcore Allgemeine Java-Themen 10
V 1000 Threads oder Iterativ? Allgemeine Java-Themen 11
4 Simple(?) Frage zu Threads Allgemeine Java-Themen 14
B Threads Game of Life - Threads Allgemeine Java-Themen 49
R Threads Exceptions von Threads abfangen im ThreadPool Allgemeine Java-Themen 5
S Threads Ende sämtlicher Threads abwarten Allgemeine Java-Themen 6
S Frage zu Threads (Sichtbarkeit und Verhalten) Allgemeine Java-Themen 11
M Java-Threads und Datentypen-Zugriffe Allgemeine Java-Themen 7
P Threads- Programming Allgemeine Java-Themen 2
G Threads Klasse Sound und Threads bleiben hängen Allgemeine Java-Themen 4
C Threads Zwei Threads greifen auf LinkedList zu. Allgemeine Java-Themen 12
M OutOfMemoryError in nebenläufigen Threads Allgemeine Java-Themen 6
M Threads dauerhafte bewegung mit threads Allgemeine Java-Themen 11
frankred Threads Auf eine Gruppe von Threads warten Allgemeine Java-Themen 11
J Eure Meinung: Threads verwenden, oder nicht? Allgemeine Java-Themen 6
K Warum wartet diese Funktion auf beenden des Threads? Allgemeine Java-Themen 3
F Mehrere Threads - ein Stack Allgemeine Java-Themen 6
O Wie kann ich das Ende eines Threads melden? Allgemeine Java-Themen 7
J Writer und Threads Allgemeine Java-Themen 2
G mehrere Threads starten/stoppen Allgemeine Java-Themen 4
E Verständnisfrage bezüglich Threads Allgemeine Java-Themen 4
K Zeitkritische Threads Allgemeine Java-Themen 14
K Threads - Swing - Synchronisation nötig? Allgemeine Java-Themen 8
S [THREADS] Thread sinnvoll beenden Allgemeine Java-Themen 2

Ähnliche Java Themen

Neue Themen


Oben