Forum: PC-Programmierung Java: Object.wait() / Object.notify() - Problem


von Jürgen W. (lovos)


Lesenswert?

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!?

von Maximilian (Gast)


Lesenswert?

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.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

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.

von Jürgen W. (lovos)


Lesenswert?

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.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

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.

von Jürgen W. (lovos)


Lesenswert?

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.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.