Thread Frage

oldshoe

Bekanntes Mitglied
Also ich habe eine Liste von Elementen. Für jedes Element soll ein Thread gestartet werden. Aber wie realisiere ich das wenn nur maximal 3 Threads gleichzeitig laufen sollen? Und wie erkenne ich wenn ein Thread zu Ende ist, damit ich das Ergebnis in der Datenbank speichern kann. Ich habe das mal mit join versucht, aber dann läuft auch nur ein Thread.
Hier mal mein unvollständiger (Pseudo)Code:

Java:
for(Element element:elementList){
Thread th1 = new Thread(..element..)
th1.start();
try{
th1.join();
saveToDatabase();
}catch(Exception e){
syso...
}
 
alles durch saubere Menschenarbeit zu lösen,

zum join:
erst mehrere Threads starten, dann auf alle joinen, dafür musst du die Threads in einer Liste ablegen,
auf die Ergebnisse am Ende zugreifen, irgendwo müssen die ja liegen, im Element vielleicht, sonst z.B. eigene Thread-Klasse

Begrenzung erreichst du genau auch durch normale Programmierbefehle,
z.B. eine Variable bis 3 zählen, dann joinen, wenn fertig dann 3 neue starten usw.,
 
Und wie erkenne ich wenn ein Thread zu Ende ist, damit ich das Ergebnis in der Datenbank speichern kann[/code]

Hi

Kann dir leider nur teilweise antworten;

Wenn du den Thread startest, rufst du die run-Methode auf, welche mit einer while-Schleife und boolean läuft.Wenn der Thread seine Aufgabe erfüllt hast, setzt du den boolean auf false, speicherst dein Ergebnis in der DB, damit die while-Schleife nicht mehr läuft.
 
zum join:
erst mehrere Threads starten, dann auf alle joinen, dafür musst du die Threads in einer Liste ablegen,
auf die Ergebnisse am Ende zugreifen, irgendwo müssen die ja liegen, im Element vielleicht, sonst z.B. eigene Thread-Klasse
Wenn ich durch diese List iterieren müsste, würde ich doch auf den ersten Thread warten müssen, obwohl andere schon fertig sein könnten. Oder verstehe ich das falsch?
Java:
th1.start();
threadList.add(th1);
th2.start();
threadList.add(th2);
for(Thread th:threadList){
try{
th.join();
saveToDatabase();
}catch(Exception e){
syso...
}
}

Begrenzung erreichst du genau auch durch normale Programmierbefehle,
z.B. eine Variable bis 3 zählen, dann joinen, wenn fertig dann 3 neue starten usw.,
So müsste ich warten bis alle 3 Threads beendet sind, damit neue gestartet werden. Wie soll der Code dazu aussehen?
 
> Wie soll der Code dazu aussehen?

du hast doch den Code schon weitgehend,
und richtig, das hat den Nachteil dass du auf den langsamsten Thread warten musst, während andere vielleicht schon fertig sind und weitere gestartet werden könnten,
dass du das erkennst macht mir ja Mut,

denkbare Erweiterungen: mit drei einzelnen Kontroll-Threads nebenläufig auf die drei Arbeits-Threads warten (joinen),
widerspricht vielleicht der begrenzten Anzahl an Threads, aber diese würden hauptsächlich schlafen, nutzen vielleicht nicht die begrenzten Arbeitsressourcen usw.

oder gar kein join einsetzen sondern normales wait/ notiy an einem Objekt, welches alle 4 Partner kennen,
der Haupt-Thread wartet darauf, jeder der 3 Arbeitsthreads kann notify aufrufen und so aufwecken,
das müsste dann aber aktiv in deinem Code am Ende der run-Methode stehen, das gemeinsame Objekt müsste überall bekannt sein

beim Aufwecken schaut der Haupt-Thread, welche(r) Thread(s) beendet ist/sind, was evtl. durch einen boolean im Thread angezeigt werden muss,
denkbar dass die run-Methode noch läuft wenn aufgeweckt wird


zu wait/ notify allgemein siehe Lehrbücher falls noch nicht bekannt
Galileo Computing :: Java ist auch eine Insel (8. Auflage) – 11 Threads und nebenläufige Programmierung

-----

ach und bevor es zuviel Einzelarbeit wird:
gibts teilweise oder sehr fortgeschritten schon fertig, Stichwort Thread-Pool, z.B. ExecutorService
 
Zuletzt bearbeitet von einem Moderator:
Hi,

eventuell solltest du auch mal einen Blick in das Package "java.util.concurrent" werfen. Insbesondere
"CountDownLatch" könnte das richtige für dich sein.
 
Mein Vorschlag:

Verwende einen ExecutorService aus dem java.util.concurrent-package. Anbieten würde sich ein FixedThreadPool mit einer Begrenzung auf 3 Threads.

Als Liste verwendest du eine synchronisierte Queue aus der sich die Threads immer ein neues Element holen. Wenn der Thread das Element fertig bearbeitet hat packt er es in eine zweite Queue.

Ein weiterer Thread holt sich parallel dazu immer drei Elemente aus der zweiten Queue (verwende hier am besten eine BlockingQueue) und speichert sie in der Datenbank.
 

Neue Themen


Zurück
Oben