Hallo an alle, ich habe folgendes Problem: ich habe ein Hauptthread (Th-1), der einen zweiten Thread (Th-2) startet. (Th-2) soll dabei in einer while-Schleife laufen. Am Ende der Schleife soll sich der Thread immer in den "wait()"-Modus versetzen, also schlafen legen. (Th-2) soll solange schlafen bis (Th-1) notify() aufruft. Dann beginnt bei Th-2 der nächste Schleifen durchlauf. Zur Anmerkung: Beide Threads sind derzeit in einer Klasse. Von der Theorie denke ich habe ich das Problem soweit gut verstanden, nur habe ich Probleme bei der Umsetzung. Es gelingt mir zwar Th-2 mit wait schlafen zu legen, jedoch nicht aufzuwecken. Ich hoffe, dass mir jemand helfen kann. Viele Grüße und vielen Dank im Voraus, Fellowes
Der schlafende Thread sollte nicht einfach eine definierte Zeit warten, sondern auf ein Synchronisationsobjekt warten. Da Du praktischerweise nichts von Programmiersprache & Betriebssystem verrätst, beschreibe ich mal einfach, wie man es mit der Win32-API macht. Ein geeignetes Synchronisationsobjekt ist hier das Event, das mit CreateEvent erzeugt wird. Mit SetEvent kann es ausgelöst werden. Das dürfte das Äquivalent Deines "notify" sein. Darauf gewartet wird mit WaitForSingleObject, dabei kann die Zeit angegeben werden, die maximal verstreichen darf -- der Rückgabewert von WaitForSingleObject hilft, herauszufinden, ob das Event ausgelöst wurde oder die Wartezeit verstrichen ist. Alternativ gibt es auch WaitForMultipleObjects, damit kann auf mehrere Events gleichzeitig gewartet werden. Wie der Namensbestandteil ..Object(s) der Funktionen schon erahnen lässt, kann mit ihnen auch auf andere Dinge als auf Events gewartet werden, so z.B. direkt auf Threadhandles (die bei Beendigung des zugehörigen Threads bedient werden).
Ohh hatte ganz vergessen zu erwähnen, dass es in Java implementiert wird und auf einem Android Tablet laufen soll
Tja, dann wirst Du Dir die Java-Dokumentation zu Gemüte führen müssen und Dir dort Synchronisationsobjekte ansehen. Ich kenne Java nicht weiter, aber vielleicht hilft Dir ja das hier: http://www.fh-wedel.de/~si/vorlesungen/java/OOPMitJava/Multithreading/Synchronisation.html
Wait/Notify ist in 99% der Fälle der falsche Weg, es gibt sehr schöne Highlevel Objekte in Java. Ohne Code/Anwendungsfall kann man dazu Garnichts sagen außer, das wenn man es richtig macht es auch funktioniert.
Es gibt prinzipiell kein Problem damit, beides in der gleichen Klasse zu implementieren. Falls die Elternklasse ein Runnable-Klasse ist (so klingen Deine Beiträge), kann damit aber nur ein Thread bedient werden und für den zweiten Thread ist ein zweites Thread-Objekt nötig, das eine andere Arbeitsmethode aufruft (falls nicht sowieso der Haupthread oder ein anderer "externer" Thread der erste Thread ist). Die Synchronisation kann man vielleicht auch mit wait() und notify() machen, ich habe aber keine Erfahrung damit und würde es daher mit einer Mutex-Semaphore machen. Der Ablauf ist folgender: - Semaphore ist am Anfang freigegeben. - T2 blockiert am Ende der While-Schleife die Semaphore - T2 wartet auf die Semaphore - T1 gibt sie frei - T2 führt nächste Runde der While-Schleife aus usw. Ich habe so was schon in C++ und in Java gemacht, habe aber leider keinen Java-Beispielcode da. Es gibt eine Semaphoren-Klasse in java.util.concurrent.Semaphore (muß mit Wert 1 initialisiert werden, um fast das gleiche wie eine Mutex-Semaphore zu erhalten). Was Dir noch weiterhelfen könnte, ist die Erklärung von Thread-Programmierung aus dem Buch "Java ist auch eine Insel": http://openbook.galileocomputing.de/javainsel9/javainsel_14_001.htm. Siehe evtl. auch http://www.oracle.com/technetwork/articles/javase/index-140767.html .
Matthias H. schrieb: > Synchronisation Kann man nicht, Synchronisation muss vorher schon gesehen sonst hagelt es Exceptions. Matthias H. schrieb: > Thread-Objekt nötig, das eine andere Arbeitsmethode aufruft Auch per se nicht korrekt... man könnte (und müßte) da die gleiche run() Methode nehmen.
Läubi .. schrieb: > Matthias H. schrieb: >> Synchronisation > > Kann man nicht, Synchronisation muss vorher schon gesehen sonst hagelt > es Exceptions. Ich wüßte nicht, wo diese herkommen sollten, außer man macht etwas anderes falsch. > Matthias H. schrieb: >> Thread-Objekt nötig, das eine andere Arbeitsmethode aufruft > > Auch per se nicht korrekt... man könnte (und müßte) da die gleiche run() > Methode nehmen. Also, entweder habe ich nicht verstanden, was Du meinst oder Du möchtest Du hier die Anfänger verwirren. 1. Es könnte technisch möglich sein, die gleiche run()-Methode zu verwenden, wenn man aus dem 2. Thread die run()-Methode des 1. Threads aufruft. Das ist aber ein schmutziger Hack, der noch eine externe Fallunterscheidung erfordert (run() hat keine Parameter!), welche der beiden Funktionalitäten nun ausgeführt werden soll. Es ist also theoretisch möglich, aber nicht sinnvoll. Steckst Du hier vielleicht gedanklich in der Semantik von UNIX-fork() oder so, wo man das so ähnlich machen muß, was aber mit Java-Threads nichts zu tun hat? 2. Wenn man beide Arbeitsmethoden in der gleichen Klasse haben möchte, gibt es (unter anderem) folgende Möglichkeiten: 2a) Klasse implementiert Runnable für Thread 2, Thread 1 ist "Hauptthread" oder "externer" Thread. Der Hauptthread ruft aber nicht run() auf, sondern eine neue Methode. 2b) Klasse 1 implementiert Runnable für einen der beiden Threads und enthält ein anderes von Runnable abgeleitetes Objekt der Klasse 2, dessen run()-Methode z. B. eine neue Methode Klasse1.run2() in Klasse 1 aufruft. Dazu muß Klasse 2 eine Referenz auf das Objekt von Klasse 1 halten. 2c) Aggregation, neue Klasse 3 enthält zwei von Runnable abgeleitete Objekte von Klasse 1 und Klasse 2. Deren run()-Methoden könnten dann neue Methoden Klasse3.run1() und Klasse3.run2() aufrufen.
Matthias H. schrieb: > Ich wüßte nicht, wo diese herkommen sollten http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#wait%28%29 >> Throws: >> IllegalMonitorStateException - if the current thread is not >> the owner of the object's monitor. Heißt: du darfst dies nur innerhalb eine syncronized Blocks aufrufen, ergo ist die Synchronisation dann schon geschehen. Matthias H. schrieb: > Es könnte technisch möglich sein, die gleiche run()-Methode zu > verwenden, wenn man aus dem 2. Thread die run()-Methode des 1. Threads > aufruft Es reicht schon beides mal das gleiche Runnable Objekt zu übergeben, das ist nicht verboten. > der noch eine externe Fallunterscheidung erfordert Nö, es kann genauso gut sein, das ich innerhalb der Run Methode von außerhalb Parameter einlese, mir errechne, ... Matthias H. schrieb: > Steckst Du hier vielleicht gedanklich in der Semantik von UNIX-fork() Nö, aber der TE kommt ja nicht aus dem Quark, hier irgendwas zu mutmaßen aufgrund von Fellowes schrieb: > Beide Threads sind derzeit in einer Klasse ist doch sehr gewagt... Matthias H. schrieb: > Das ist aber ein schmutziger Hack Ach und eine run1(), run2() und run3() trägt nun zur allgemeine Erleuchtung bei ;-P Das ist doch erst recht Käse... Ohne konkretes Problem/Code kann man hier doch eh nix vernünftiges Raten und aufgrund der spärlichen Informationen noch nicht mal richtig mutmaßen....
Läubi .. schrieb: >> Ich wüßte nicht, wo diese herkommen sollten > > http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#wait%28%29 > >>> Throws: >>> IllegalMonitorStateException - if the current thread is not >>> the owner of the object's monitor. > > Heißt: du darfst dies nur innerhalb eine syncronized Blocks aufrufen, > ergo ist die Synchronisation dann schon geschehen. Das ist genau der Grund, warum ich eine Lösung mit Semaphore anstelle von wait()/notify() vorgeschlagen hatte.
Matthias H. schrieb: > anstelle von wait()/notify() vorgeschlagen hatte Ja und ich hab schon ganz am Anfang gesagt das es fast immer bessere Lösungen gibt. Aber da der TE ja nicht mit Details rausrückt...
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.