Multi-Threading mit join()

Luk10

Top Contributor
Hallo,

Vorab: Ja ich weiß es gab schon viele Themen dazu, aber keins hat mir wirklich weitergeholfen, da es mir hier um Grundlagen geht.

> Ich habe eine List von Objekten die in einer Endlosschleife immer wieder abgearbeitet werden muss (Berechnungen auf den Objekten durchführen).
> Ich will, dass das abarbeiten der Objekte auf 2 (4) Threads verteilt wird um die CPU voll auszulasten

Meine Fragen:
> Wo und wann werden die Threads erstellt? (Ständig neue Threads? Nur einmal 2 (4) Threads?)
> Was genau passiert in der run() Methode? (Endlosschleife und warten auf neue Teilliste? Nur eine! Abarbeitung der Teilliste?
> Wo und wann muss join() verwendet werden und was genau macht es?

Wäre auch dankbar wenn ihr mir dazu ein Tutorial-Link geben könntet. "Java ist auch eine Insel" hilft mir nicht, hab ich schon angeschaut.

-Luk10-
 
Ich stelle fest du bist fast 3 Jahre Mitglied in diesem Forum. Da hätte ich so ein Posting nicht erwartet.

Vorab: Ja ich weiß es gab schon viele Themen dazu, aber keins hat mir wirklich weitergeholfen, da es mir hier um Grundlagen geht.

Wieso haben sie dir nicht geholfen? Welche Tutorials? Wieso müssen wir Links suchen, die auch google finden kann?

Meine Fragen:
> Wo und wann werden die Threads erstellt? (Ständig neue Threads? Nur einmal 2 (4) Threads?)
> Was genau passiert in der run() Methode? (Endlosschleife und warten auf neue Teilliste? Nur eine! Abarbeitung der Teilliste?
> Wo und wann muss join() verwendet werden und was genau macht es?

Ich finde es merkwürdig, dass zu dazu keine Antworten gefunden hast. Das sind ja keine Fragen, wo man sagt: UHHH noch nie gehabt.

1) Wieso sollten, wenn ich 2 Threads erstelle immer wieder neue Threads erstellt werden?

2) In Run methode passiert genau das, was du implementiert hast.

3) Siehe JavaDoc.

Wäre auch dankbar wenn ihr mir dazu ein Tutorial-Link geben könntet. "Java ist auch eine Insel" hilft mir nicht, hab ich schon angeschaut.

Wo hast du den ein Problem?
 
Ich würde eine (!) LinkedBlockingQueue für alle 4 Threads benutzen. Mit take() holen sie sich einfach die Elemente, arbeiten sie ab und kehren zum Anfang zurück. Dann hast du einen Aufbau ähnlich den EDT: Von außen werden Operations-Events eingetragen und die Threads arbeiten sie ab. Rückgabe der Ergebnisse könnte per Listener erfolgen. Oder direkt eingetragen in die Events, obwohl Listener vermutlich einfacher zu managen sind.

join() wirst du vermutlich garnicht brauchen, das blockiert den aufrufenden Thread bis der aufgerufene Thread terminiert.
 
Mir ist sehr wohl bewusst, dass man vorher selber auf Google / Youtube sucht bevor man etwas fragt. Das habe ich auch getan. Hättest du das auch getan hättest du vielleicht herrausgefunden, dass es da nicht wirklich viel gutes, Grundlagen-erklärendes gibt!

3) Siehe JavaDoc.

Ich kann JavDoc lesen. Da steht:
Waits for this thread to die.
An invocation of this method behaves in exactly the same way as the invocation

Was soll das bedeuten? "Waits for this thread to die"? Wieso soll der Thread sterben? Dann müsste ich ja ständig neue erstellen.

Die meisten Tutorials die ich angeschaut habe, verwenden keine "endlose" Abarbeitung von einer Liste und müssen sich nicht den Fragen stellen wie die Wiederholung umgesetzt werden soll.

Nur weil für dich einige Ding "offensichtlich" sind, sind sie es für mich nicht!

-Luk10-
 
Der Thread stirbt, sobald die run-Methode nach außen verlassen wurde. Und der Aufrufer wartet eben bis der Thread, von dem join() aufgerufen wurde terminiert. Hat ja keiner gesagt, dass du das brauchen wirst.

btw. auf YT habe ich noch nie gesucht. Oo
 
Was machen Threads in der Zeit, in der sie gerade keine neuen Objekt mit take() holen können, weil keine mehr in der Liste sind und extern die Liste wieder aufgefüllt werden muss?

[OT]Auf Youtube gibt es eine Fülle an mehr oder weniger guten Tutorials[/OT]
 
Was machen Threads in der Zeit, in der sie gerade keine neuen Objekt mit take() holen können, weil keine mehr in der Liste sind und extern die Liste wieder aufgefüllt werden muss?

Entweder schlafen (sleep) oder sterben 😉 (Klingt witzig ist aber so ^^)

as habe ich auch getan. Hättest du das auch getan hättest du vielleicht herrausgefunden, dass es da nicht wirklich viel gutes, Grundlagen-erklärendes gibt!

:lol:
 
Hallo,


> Ich will, dass das abarbeiten der Objekte auf 2 (4) Threads verteilt wird um die CPU voll auszulasten

Meine Fragen:
> Wo und wann werden die Threads erstellt? (Ständig neue Threads? Nur einmal 2 (4) Threads?)
> Was genau passiert in der run() Methode? (Endlosschleife und warten auf neue Teilliste? Nur eine! Abarbeitung der Teilliste?
> Wo und wann muss join() verwendet werden und was genau macht es?

Wäre auch dankbar wenn ihr mir dazu ein Tutorial-Link geben könntet. "Java ist auch eine Insel" hilft mir nicht, hab ich schon angeschaut.

-Luk10-


Das was du suchst ist ein "Threadpool".
Dazu stellt Java die Schnittstelle Executer und eine Utility-Klasse Executors bereit.
Da die Konstruktoren der Executer nicht ganz trivial sind, bietet die Utility-Klasse einen einfacheren Zugang.

So liefert
Java:
ExecutorService executor = Executors.newFixedThreadPool( int n )
einen Thread-Pool mit maximal n Threads.

Diesem Threadpool können nun beliebig Objekte vom Typ runnable übergeben werden:

Java:
executor.execute( r1 ); 
executor.execute( r2 );

...

executor.execute( r100 ); 
executor.shutdown();

Dabei sind r1 bis r100 alles runnable-objects, die nun durch die n Threads abgearbeitet werden.

Da die n Threads des Threadpool ja nie sterben würden, musst du den Threadpool am Ende mit dem shutdown() "herunterfahren". Das bewirkt nichts anderes, als dass alle n Threads nun beendet werden und damit sterben.

Gruß
JP
 
Zuletzt bearbeitet:
Da die n Threads des Threadpool ja nie sterben würden, musst du den Threadpool am Ende mit dem shutdown() "herunterfahren". Das bewirkt nichts anderes, als dass alle n Threads nun beendet werden und damit sterben.

Eine kleine aber wichtige Ergänzung noch.
Ein shutdown() beendet die Threads nicht sofort.
Es sorgt zunächst dafür, dass keine neuen Jobs mehr vom Threadpool angenommen werden und erst wenn alle Jobs im jobbuffer abgearbeitet sind, dann terminieren die Threads.

Gruß
JP
 
Kann man mit dem executor auch nach einer Runde "Abarbeiten" die Ergebnisse verarbeitet werden, bevor eine neue Runde Objekte abgearbeitet wird?
 
An welchem Punkt in der Methode sind alle tasks abgearbeitet?

Java:
try {

	executor.invokeAll(tasks);

} catch (InterruptedException e) {

	e.printStackTrace();

}

// Sind hier alle tasks abgearbeitet?
 
Kann man mit dem executor auch nach einer Runde "Abarbeiten" die Ergebnisse verarbeitet werden, bevor eine neue Runde Objekte abgearbeitet wird?

JA über das interface "callable" und "Future"-Objekten und in deinem beschrieben fall mit einem ScheduledExecutorService. an statt eines normalen ExecutorService

Gruß
JP
 
Zuletzt bearbeitet:
An welchem Punkt in der Methode sind alle tasks abgearbeitet?

Wie auch in der Doku steht, sind ist nach
executor.invokeAll(tasks);
alle Tasks aus der übergebenen Liste abgearbeitet. Ggf. kann man danach einen neuen Stapel Tasks als list übergeben. Es scheint mir aber, als wäre es gut, wenn du genauer beschreiben würdest, was du vorhast....
 
also ich würde mir "ForkJoin" ansehen, gibts wohl erst seit java 7.

ansonsten haste 4 threads, die erstmal tot sind und nur deklariert sind.

und dann hab ich das immer so gemacht: while (counter < liste.size()) if (!(thread1.isAlive()) thread1 = new thread1(...)... counter++..;

und nach der while schleife einfach abfragen ob alle 4 threads noch alive sind, falls einer alive ist dann den join() und fertig. auslastung 100%
 

Neue Themen


Zurück
Oben