ich habe in meinem Programm einen InputStream mInput, dessen Inhalt sich in unregelmäßigen Abständen ändert. Jedes mal wenn sich der Inhalt ändert soll er analysiert werden.
Um ihn auf Veränderung zu prüfen, habe ich bisher folgenden Code:
Java:
String refdata ="";//output ist ein String der den Inhalt des InputStreams enthält.//output wird bei Änderung des InputStreams mInput mitverändert (anderer Thread)while(true){while(output.equals(refdata)){Thread.yield();}
refdata = output;System.out.println("<!-- Event triggered. -->");}
Das Problem hierbei ist allerdings der unverhältnissmäßige Ressourcenverbrauch. Zwar verwende ich Thread.yield(); aber das scheint nicht viel zu helfen. An dem Verbrauch ist wohl die ständige Prüfung der while-Bedingung Schuld.
Jetzt will ich fragen ob es einen entsprechenden Listener gibt, der bei Veränderung eines InputStreams ausschlägt und somit von sich aus meldet ob was passiert ist, statt die ganze Zeit aktiv zu überprüfen zu müssen.
Jetzt will ich fragen ob es einen entsprechenden Listener gibt, der bei Veränderung eines InputStreams ausschlägt und somit von sich aus meldet ob was passiert ist, statt die ganze Zeit aktiv zu überprüfen zu müssen.
Was meinst Du mit "Veränderung eines InputStreams"?? Das ist ein Datenstrom, dessen Inhalt man ausliest. Wie willst Du da einen Listener an den Datenstrom hängen?
Das Lesen eines Datenstroms ist blockiert, d.h. der Thread wartet solange bis es was zu lesen gibt. Man kann also einfach den Stream auslesen und auf Schlüsselwörter/daten reagieren.
also ich weiß jetzt nicht ob das passt, oder ob das richtig ist, aber mal rein von der Logik her gesehen:
Ein Stream ist doch ein kontinuierlicher Fluss an Bytes. Solange Bytes zum Lesen/Schreiben vorhanden sind, dann ändert sich auch der Stream. Wenn keine Zeichen vorhanden sind, dann ändert sich der Stream nicht. Dazu gibt es ja die Methode read(), die beim Ende -1 zurück gibt. Vielleicht kannst du die -1 abfragen. D.h. erst wenn du das Ende des Streams erreicht hast, vergleiche den String. Ansonsten vergleicht er ja bei jeder Zeichenänderung?! den String.
Oder mit available() abfragen, wie viel gelsen werden kann. Lesen. Dann vergleichen, und so weiter?
Ansonsten (zusätzlich) das Observer-Pattern implementieren und bei Veränderung des InputStreams, d.h. aber erst wenn er ganz gelesen ist, alle Observer benachrichtigen?
Was meinst Du mit "Veränderung eines InputStreams"?? Das ist ein Datenstrom, dessen Inhalt man ausliest. Wie willst Du da einen Listener an den Datenstrom hängen?
Das Lesen eines Datenstroms ist blockiert, d.h. der Thread wartet solange bis es was zu lesen gibt. Man kann also einfach den Stream auslesen und auf Schlüsselwörter/daten reagieren.
Wenn ich den InputStream auslese ist er ja zwischendurch irgendwann leer (zumindest wenn die Daten in Abständen kommen). Wenn dann wieder was kommt und er nicht mehr leer ist dann sollen die neu angekommenen Daten irgendwie verarbeitet werden ("<!-- Event triggered. -->").
Meine Frage war ob es eine Möglichkeit gibt (evtl. Listener oder ähnliches) dass das Event von sich aus ausgelöst wird und nicht andauernd wie in meinem Code-Beispiel AKTIV geschaut werden muss ob neue Daten ankommen.
Wenn ich den InputStream auslese ist er ja zwischendurch irgendwann leer (zumindest wenn die Daten in Abständen kommen). Wenn dann wieder was kommt und er nicht mehr leer ist dann sollen die neu angekommenen Daten irgendwie verarbeitet werden ("<!-- Event triggered. -->").
Meine Frage war ob es eine Möglichkeit gibt (evtl. Listener oder ähnliches) dass das Event von sich aus ausgelöst wird und nicht andauernd wie in meinem Code-Beispiel AKTIV geschaut werden muss ob neue Daten ankommen.
Du vergleichst oben aber nicht, wenn neue Daten ankommen - du vergleichst die ganze Zeit mit deiner Endlosschleife. Du kannst ja mit read() => -1 erst ab dem Zeitpunkt vergleichen, wenn keine neuen Daten mehr ankommen?!
Meine Frage war ob es eine Möglichkeit gibt (evtl. Listener oder ähnliches) dass das Event von sich aus ausgelöst wird und nicht andauernd wie in meinem Code-Beispiel AKTIV geschaut werden muss ob neue Daten ankommen.
Wie gesagt das Lesen vom Stream ist blockierend. Es wird einfach weiter gelesen, sobald es etwas zu lesen gibt und es muss nicht aktiv nachgeschaut werden, ob es auf dem Stream was neues zum Lesen gibt. Der Thread pausiert solange.
Das was Du versuchst mit dem "Listener" nachzubauen, ist bereits im Auslesemechanismus implementiert.
Du vergleichst oben aber nicht, wenn neue Daten ankommen - du vergleichst die ganze Zeit mit deiner Endlosschleife. Du kannst ja mit read() => -1 erst ab dem Zeitpunkt vergleichen, wenn keine neuen Daten mehr ankommen?!
Ja aber das muss ich ja auch wieder regelmäßig prüfen.
Wie dem auch sei, es funktioniert jetzt.
Im Prinzip war die entscheidende Tatsache dass ich jetzt weiss dass mInput.read(); solange blockt bis wieder was kommt.
Mal abgesehen von deinen Inputstreams hast du es hier mit dem klassischen Producer-Consumer Design-Pattern zu tun.
Du benutz am Besten eine LinkedBlockingQueue (Java Platform SE 6). Die ist bereits synchronisiert und blockt den Lese-Thread falls die Queue leer ist und du auf einen neuen Inputstream warten musst. Alternativ kannst du auch das alte Synchronized-Wait-Notify Pattern verwenden.
Java:
//Producer.java// neuen InputStream in die Queue legen
queue.offer(newInputStream);// Consumer.javaBlockingQueue<InputStream> queue =newLinkedBlockingQueue<InputStream>();publicvoidrun(){while(true){InputStream is = queue.take();// do something....}}