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.
Uups, da ist wohl etwas mit der Formatierung schief gegangen…
Poste am besten eine kompilierbares Testprogramm (mit lesbaren Variablenbezeichneren)
Wenn ich das richtig überblicke rufst Du wait() und notify() an jeweils unterschiedlichen Objekten auf. wait am Runnable und notify am Thread der das Runnable ausführt.
Sooo, ich habe mal versucht das alles in eine neue Klasse unter Java direkt zu packen. Es ist leider nicht so kompilierbar, da es für Android geschrieben ist (da gibt es den extra Thread/Runnable runOnUiThread(new Runnable() {})
Ich hoffe es hilft euch weiter.
public class test {
static long counter=0;
static Thread threadRX;
static Thread thread__GUI;
static boolean thread__GUI_wait;
/**
* @param args
*/
public static void main(String[] args)
{
threadRX = new Thread(null, _runnable_1, "TAG");
threadRX.setDaemon(true); //sorgt dafür, dass dieser Thread mit beenden des Hauptprogramms beendet wird
// Diese Methode ist nur vor dem STart des Threads erlaubt
threadRX.start();
}
static Runnable _runnable_1 = new Runnable()
{
@Override
public void run()
{
while (true)
{
counter++;
if(counter == 1)
{
start();
}
else
resume();
}
}
};
public static void start()
{
thread__GUI_wait = true;
thread__GUI = new Thread(null,_runnable_commRunnableGUI_RT_intervall, "TAG");
thread__GUI.start();
}
public static void resume()
{
synchronized (thread__GUI)
{
thread__GUI_wait = false;
thread__GUI.notify();
}
}
static Runnable _runnable_commRunnableGUI_RT_intervall = new Runnable()
{
@Override
public synchronized void run()
{
runOnUiThread(new Runnable()
{
@Override
public void run()
{
while (thread__GUI == Thread.currentThread())
{
synchronized(thread__GUI)
{
while(thread__GUI_wait)
{
try
{
thread__GUI.wait();
} catch (InterruptedException e)
{
}
}
}
}
}
});
}
};
}
Ist denn diese Bedingung jemals erfüllt? In dem Code ist nichts zu sehen, dass dieser Thread dieses Runnable ausführt (abgesehen, davon dass der Thread bereits eine anderes Runnable (_runnable_commRunnableGUI_RT_intervall) ausführt und danach eigentlich „tot“ ist).
Wo wird thread__GUI_wait jemals wieder true - außer in start?
Wenn es für Android ist, warum nutzt nicht die Android spezifischen Mechanismen wie Handler, AsyncTasks… ? Was versuchst Du da zu implementieren? Evlt. gibt es da bessere Wege.
mhhh du scheinst recht zu haben… also, dass was ich versuche zu implementieren ist folgendes:
Ein Thread der die grafische Ausgabe macht/aktualisiert, soll in einer endlosschleife laufen und nach jedem durchlauf sich schlafen legen bis er extern getriggert wird, dann arbeitet der Thread weiter. der Externe Trigger soll in einem Thread erfolgen der umfangreiche Berechnung vornimmt. erst wenn neue Ergebnisse vorliegen soll es auf der GUI geupdatet werden. Deswegen der Ansatz mit wait() und notify().
Wenn es also einfach nur darum geht an bestimmten Punkten ein Update des UI durchzuführen, dann nutze z.B. einen Handler:
Erstelle einen Handler und überschreibe dessen handleMessage(Message msg) in dieser Methode implementierst Du den UI Update.
Sorge dafür, dass Du innerhalb des Rechenthreads bzw. in der run des Runnables (hier kannst Du weiterhin Thread & Runnable nutzen) auf das Handler Objekt zu greifen kannst.
Immer wenn aus dem Thread heraus eine Update des UI angestossen werden soll rufst Du handler.sendEmptyMessage(0); am Handler Objekt auf. Da ja nur ein Update angestossen werden soll, sollte eine EmptyMessage für den Zweck ausreichen. )Ansonsten bietet Handler noch weitere Methoden sendMessage, post…)
Je nachdem was genau Du da machst solltest Du Dir evtl. auch mal das Thema Service anschauen.
Mit einem Handler habe ich bisher noch nicht gearbeitet. Nun werde ich mich damit mal beschäftigen
kurze Frage dazu: ist der Handler eine Referenz auf den UI-Thread? oder wie darf ich ihn ganz grob verstehen (nur damit ich eine Vorstellung davon bekomme)?
So ganz grob: Die Methode handleMessage wird in dem Thread ausgeführt in dem der Handler erzeugt wurde. Das muss nicht unbedingt der UI -Thread sein.
Wenn Du aber den Handler im UI Thread erzeugst ist das ähnlich dem SwingUtilities.invokeLater unter Swing, vor allem die post Variante lässt gewisse Parallitäten erkennen.