Java: Object.wait() / Object.notify() - Problem

OP #2959123
Hallo,
es geht um den Sample-Code bei
http://www.mikrocontroller.net/attachment/93725/SampleSPPClient.java
Ich weiß nicht, zu welchen Thread der Code gehört, den Link hat mir 
Gugel ausgespuckt.

Der Code funktioniert zwar wunderbar, aber eine Stelle kommt mir komisch 
vor.
Es geht um den Object.wait() / Object.notify() Mechanismus.
Zuerst werden alle BT-Devices gesucht und das Hauptprogramm angehalten.
1
agent.startInquiry(DiscoveryAgent.GIAC, client);
2
synchronized(lock) {
3
  lock.wait();
4
}

Wenn die Suche beendet ist, wird in der vom DiscoveryListener 
bereitgestellten Funktion das Hauptprogramm wieder losgefahren.
1
public void inquiryCompleted(int discType) {
2
        synchronized(lock){
3
            lock.notify();
4
        }
5
    }

Das gleiche Spiel wird bei der Suche der Services des ausgewählten 
BT-Device gemacht: Hauptprogramm angehalten, bei Beendigung der Suche 
wieder fortgesetzt.
Allerdings wird in 2 Callbacks lock.notify() aufgerufen:
servicesDiscovered() und serviceSearchCompleted().
D.h. schon beim ersten gefundenen Service läuft das Hauptprogramm 
weiter.

Ich habe den lock.notify() in der servicesDiscovered() herausgenommen, 
dann funktioniert das Sample-Programm auch.
Was ist die richtige/bessere Version?
Ich kann mir vorstellen, dass manche Treiber serviceSearchCompleted() 
gar nicht aufrufen, dann bliebe das Hauptprogramm stecken. Vielleicht 
hat man sicherheitshalber ein überflüssiges lock.notify() angefügt!?
Gast
Unabhängig vom konkreten Code: notify ist in Java ein disaster waiting 
to happen. Man sollte immer notifyall verwenden, sofern man nicht ganz 
genau analysiert hat, was da passieren mag.
Persönliche Seite
Jürgen W. schrieb:
> aber eine Stelle kommt mir komisch vor
Nur eine? ;-)

Der Code ist... sagen wir mal supoptimal, hier der Thread wo ich auch 
eine alternative gepostet habe welche komplett ohne waits auskommt:
Beitrag "[Java] Bluetooth <-> BTM222"

wait/notify benötigt man ganz ganz ganz selten direkt, fast immer gibt 
es bessere und erprobte Wege auf höherem Level und wenn man es benutzt 
sollte man verstehen wie es funktioniert, siehe auf Beitrag vom 
Maximilian.
OP
Ich habe exakt den gleichen Code schon bei 2 Bluecove-Tutorials 
gefunden, z.B.
http://www.jsr82.com/jsr-82-sample-spp-server-and-client/


>Autor: Christian J. (stormracer)
>Datum: 27.11.2010 23:04
>Habe gerade festgestellt, das die ganze Methode servicesDiscovered()
>überhaupt nicht ausgeführt wird. Weshalb auch immer...

Da haben wir den Grund, warum das "zusätzliche" Notify() drinsteht.
Bei mir wurde servicesDiscovered() allerdings schon ausgeführt.
Persönliche Seite
Das kann ja sein, ich glaube der TE hatte den auch genau daher, macht es 
aber nicht besser (vermutlich einfach voneinander kopiert...)! Der Code 
ist bestenfalls als Quick&Dirty Lösung für die Demonstration brauchbar, 
aber nicht für eine produktive Implementierung.

Der Beispielcode ist einfach der Versuch, eine Asyncrone Abfrage zu 
serialisieren sodass der Code einmal durchlauft und sich dann beendet, 
dass könnte man in meiner Lösung auch nachrüsten, in einem Realem 
Programm will man aber meist eh nicht das das Programm sich sofort 
wieder beendet.
OP
Den gleichen Fehler wie der "Christian J. (stormracer)" hatte ich auch:
"Device does not support Simple SPP Service."
Stellte aber fest dass im SPP-Server Code
1
uuidSet[0]=new UUID("1101",true);
stand, und habe im Client-Code
1
uuidSet[0]=new UUID("1101",false);
in
1
uuidSet[0]=new UUID("1101",true);
geändert.
Dann gings. Das boolean bezieht sich auf die Adresslänge, genaueres weiß 
ich nicht. ("try and error" in der Praxis)
Aber ich vermute, dass er "stormracer" sich jetzt nicht mehr für die 
Lösung interessiert.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 13 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.