Wie mehreren Threads Aufgaben zuweisen und abarbeiten lassen?

P@

Mitglied
Hallo allerseits,

bin neu hier im Forum. Hab schon einige Erfahrungen mit Java gemacht, beiße mir aber am Thema Threads die Zähne aus. Während ich mich u.a. durch die Java-Insel und einige Tutorials gequält habe, sind schon etliche Programmierversuche ins Land gegangen. Meine Versuche mit synchronized, volatile, wait, notify und Co. haben bei mir nur dazu geführt, das mehrere Threads nacheinander und nicht parallel von einem Hauptthread bedient wurden. Da habe ich wohl was nicht richtig verstanden.
In dem folgenden Programm habe ich einfach mal drauf losgelegt und das Ergebnis scheint so zu funktionieren, wie ich's mir vorstelle: parallel und - ich hoffe - fehlerfrei.

Im s.g. Hauptthread (Ht) werden zwei Threads (Consumer) erzeugt und mit Aufgaben (Zahlen) gefüttert. Hat ein Thread eine Aufgabe erledigt, durchläuft er ständig eine Schleife, um zu prüfen, ob der Ht eine weitere Aufgabe für ihn hat. Nach erfolgreicher Bearbeitung wird, als Signal erneuter Aufnahmebereitschaft an den Ht, ein Trigger auf false gesetzt. Dieser wird zyklisch vom Ht abgefragt. Erkennt dieser den Trigger als false, schickt er erneut eine Aufgabe an den jeweiligen Thread und setzt dessen Trigger auf true, was für den Consumer wiederum das Signal zum erneuten run-Durchlauf ist.
Wenn alle Aufgaben erledigt sind, erhält jeder Consumer-Thread ein Abbruchsignal (-1 als Aufgabe), um sich selber zu beenden.

Java:
public class Consumer extends Thread{
	private String name;
	private boolean trigger;
	private int aufgabe; //Was der Thread machen soll
	
	public Consumer( String n ){
		this.name= n;
		this.trigger= false;
		this.aufgabe= 0;
	}
	
	public void setAufgabe( int a ){
		this.aufgabe= a;
	}
	
	public boolean getTrigger(){
		return this.trigger;
	}
	
	public void setTrigger(){
		this.trigger= true;
	}
	
	public void run(){
		while( true ){
			while( !trigger ){
				try { sleep( 1 ); } catch ( InterruptedException e ){ e.printStackTrace(); }
			}
			/********** Aufgabenbereich *****************************************************/
			
			if( aufgabe== -1 ){ // -1 als Abbruchsignal, Thread beenden
				System.out.println("\n" + name + " beendet" );
				break;
			}
			System.out.println( name + "  " + aufgabe );
			try { sleep( aufgabe ); } catch ( InterruptedException e ){ e.printStackTrace(); }
			
			/********************************************************************************/
			
			trigger= false;
		}
	}
	
	public static void main(String[] args) {
		int[] aufgaben= { 10, 20, 30, 40, 500, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200 };
		int threadanz= 2;
		
		/***** erzeugen und starten von 2 (threadanz) Consumer-Threads *************/
		Consumer []c= new Consumer[threadanz];
		for( int i= 0; i< threadanz; i++ ){
			c[i]= new Consumer("c" + i);
			c[i].start();
		}
		
		/***** abarbeiten des aufgaben-Arrays ***************/
		int i= 0;
		int j= 0;
		while( i< aufgaben.length ){
			if( j>= threadanz ) j= 0;
			if( !c[j].getTrigger() ){
				c[j].setAufgabe(aufgaben[i]);
				c[j].setTrigger();
				i++;
			}
			j++;
		}
		
		/***** alle Consumer-Threads erhalten das Signal zum Beenden (-1) ****/
		i= 0;
		while( i< c.length ){
			if( i>= c.length ) i= 0;
			if( !c[i].getTrigger() ){
				c[i].setAufgabe(-1);
				//c[i].interrupt();
				c[i].setTrigger();
				i++;
			}
		}
	}
}

Meine eigentliche Frage bzw. Bitte lautet nun, mir die richtige Richtung zu weisen. Sprich: Hat jemand einen besseren Lösungsvorschlag, um mehrere Threads bestimmte Aufgaben parallel abarbeiten zu lassen. Ich bitte Euch um aktive Meinungsäußerung.
Und noch etwas. Wie ich bereits erwähnte, bin ich neu hier in diesem Forum. Das soll heißen, dass man mir, falls dieses Threads-füttern-Thema hier bereits zur Genüge gefragt, diskutiert und behandelt wurde, vergeben möge. Gleiches gilt für den Fall, dass ich zu :autsch: sein sollte, nach dem richtigen Foreneintrag zu suchen.
Ich bin für jede Hilfe und jeden Hinweis dankbar.

MfG Patrick
 
Zuletzt bearbeitet:

Andi_CH

Top Contributor
Hm, ich verstehe dein Problem nicht. Dein Programm erzeugt bei mir den output unten und da kann man erkennen, dass sich die threads schön brav abwechseln. Allerdings starte ich das aus Eclipse und wenn du es direkt auf eine VM startest könnte das schon ein verändertes Taskswitching bedeuten.

Ich vermute der Code macht das was du wolltest.

Code:
c1  20
c0  10
c0  30
c1  40
c0  500
c1  60
c1  70
c1  80
c1  90
c1  100
c1  110
c0  120
c1  130
c0  140
c1  150
c0  160
c1  170
c0  180
c1  190
c0  200

c1 beendet

c0 beendet
 

P@

Mitglied
Hm, ich verstehe dein Problem nicht. Dein Programm erzeugt bei mir den output unten und da kann man erkennen, dass sich die threads schön brav abwechseln. Allerdings starte ich das aus Eclipse und wenn du es direkt auf eine VM startest könnte das schon ein verändertes Taskswitching bedeuten.

Ich vermute der Code macht das was du wolltest.

Code:
c1  20
c0  10
c0  30
c1  40
c0  500
c1  60
c1  70
c1  80
c1  90
c1  100
c1  110
c0  120
c1  130
c0  140
c1  150
c0  160
c1  170
c0  180
c1  190
c0  200

c1 beendet

c0 beendet

Hallo Andi,

exakt, gerade ab
Code:
c0 500
lässt sich sehr schön erkennen, dass c1 weiterhin "gefüttert" wird, während c0 noch beschäftigt ist.
Ich programmiere auch mit Eclipse. Aber wegen Deiner Bedenken bezüglich des veränderten Taskswitchings kann ich sagen, dass das Programm als jar-Datei, unter Windows und Linux die gleiche Ausgabe wie unter Eclipse erzeugt, falls Du das gemeint haben solltest.

MfG Patrick
 

P@

Mitglied
Producer-Consumer Probleme löst man z.B. mit Mutex aus dem concurrency package. Es gibt da noch mehr tolle Implementierungen, die das Handling mit Threads nicht mehr nötig machen.

Concurrent Programming with J2SE 5.0

Hallo FArt,
vielen Dank für Deine Antwort inkl. dem Link. Ja, diese "lustigen" Semaphoren. Was das ist, und was es macht, habe ich schon begriffen. Leider hapert's da bei mir an der Umsetzung. Wie ich bereits erwähnte, haben meine bisherigen Versuche mit synchronized & Co. - und dazu gehört auch leider der Semaphoren-Ansatz - nur dazu geführt, dass der Hauptthread immer warten musste, bis die Consumer ihre Locks wieder freigegeben haben, wodurch sie lediglich seriell und nicht parallel abgearbeitet wurden. Ich hoffe, ich drücke mich klar genug aus. Deshalb galt ja meine eigentliche Bitte dem Einbringen von Vorschlägen, Codeschnipseln, wie man dies z.B. mittels Semaphoren parallelisieren kann.

MfG Patrick

PS: Kannst Du mir bitte erklären, wie du auf den Link zu dem Artikel bei sun.com gekommen bist?
 
Zuletzt bearbeitet:

P@

Mitglied
Nachtrag:

Ein entscheidendes Problem ist, dass wenn die Consumer-Threads ziemlich lange mit einer Aufgabe beschäftigt sind, der Hauptthread sich in einer Art Endlosschleife beim Abfragen der ist-bereit-Zustände der Consumerthreads (Trigger) tot macht; deutlich sichtbar an der Prozessorauslastung. Dafür bräuchte ich eine optimierte Lösung.

Ich möchte an dieser Stelle nochmals allen danken, die sich bisher für mein Problem interessiert haben.

MfG Patrick
 
Zuletzt bearbeitet:

andiv

Bekanntes Mitglied
Schau dir mal an wie ich das ganze (ungefähr) umsetzen würde:

Java:
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;


class Consumer implements Runnable {
	
	private final String name;
	private final BlockingQueue<Integer> queue;
	
	public Consumer(String name, BlockingQueue<Integer> queue) {
		this.name = name;
		this.queue = queue;
	}
	
	@Override
	public void run() {
		try {
			while(true) {
				// Aufgabe aus Queue entnehmen, take blockiert falls Queue leer ist
				Integer task = queue.take();
				
				// Aufgabe -1 als Abbruchsignal
				if(task == -1) {
					break;
				}
				
				// Eigentliche Aufgabe ausführen
				System.out.println(name + " Aufgabe " + task);
				Thread.sleep(task);
			}
		} catch(InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println(name + " beendet");
	}
}

public class Test {
	
	public static void main(String[] args) {
        int[] tasks = { 10, 20, 30, 40, 500, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200 };
        // Maximal 10 Aufgaben in Queue halten
        BlockingQueue<Integer> queue = new LinkedBlockingQueue<Integer>(10);        
        
        // Maximal 2 Threads verwenden
        int numberOfThreads = 2;
        ExecutorService executor = Executors.newFixedThreadPool(numberOfThreads);
        
        // 2 Consumer ausführen
        for(int i = 0; i < numberOfThreads; i++) {
        	executor.execute(new Consumer("c" + i, queue));
        }
        
        try {
        	// Aufgaben nacheinander in Queue einfügen, put blockiert falls Queue voll ist
	        for(int i = 0; i < tasks.length; i++) {
	        	queue.put(tasks[i]);
	        }
	        // Abbruchsignal in Queue einfügen
	        for(int i = 0; i < numberOfThreads; i++) {
	        	queue.put(-1);
	        }
        } catch(InterruptedException e) {
        	e.printStackTrace();
        }
        
        // Alle Threads beenden
        executor.shutdown();
	}
}
 

jgh

Top Contributor
Nachtrag:

Ein entscheidendes Problem ist, dass wenn die Consumer-Threads ziemlich lange mit einer Aufgabe beschäftigt sind, der Hauptthread sich in einer Art Endlosschleife beim Abfragen der ist-bereit-Zustände der Consumerthreads (Trigger) tot macht; deutlich sichtbar an der Prozessorauslastung. Dafür bräuchte ich eine optimierte Lösung.
...

du lässt deine HT aber auch nicht viel Zeit^^
Java:
while (!trigger) {
				try {
					sleep(1);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
sleep(1) ist 1ms, deine eigentlichen Tasks legst du aber mindestens 10, im Extremfall 500 ms schlafen...evtl. kannst du da dynamisch eine Variable setzen, die in Abhängigkeit der Aufgabenlänge steht. Ansonsten würde ich an deiner stelle diesen Wert einfach erhöhen.
 

P@

Mitglied
Ich glaub der andiv hat's. Ich werd verrückt. Alles läuft parallel, und der Hauptthread macht sich nicht mehr tot, wenn die Consumer etwas länger mit ihren Aufgaben beschäftigt sind. Menschenskind, beim Barte Odins, Heureka und fettes, fettes Merci Andi (entschuldigung, aber ich freu mich eben). Werd mir den Code glaub ich einrahmen lassen.
Kurze Anmerkung: Es funktioniert auch, wenn man queue mit einer Größe von 1 initialisiert &
darf ich fragen, ob Du mir weiterführende Literatur empfehlen kannst?

MfG Patrick
 
Zuletzt bearbeitet:

P@

Mitglied
du lässt deine HT aber auch nicht viel Zeit^^
Java:
while (!trigger) {
				try {
					sleep(1);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
sleep(1) ist 1ms, deine eigentlichen Tasks legst du aber mindestens 10, im Extremfall 500 ms schlafen...evtl. kannst du da dynamisch eine Variable setzen, die in Abhängigkeit der Aufgabenlänge steht. Ansonsten würde ich an deiner stelle diesen Wert einfach erhöhen.

Diese Idee ist mir auch schon gekommen. Allerdings sollen die Consumer im fertigen Progi nicht einfach nur eine best. Zeit lang schlafen, sondern Bilder von png in jpg umwandeln. Man könnte zwar z.B. in Abhängigkeit der Dateigröße eine dynamische Variable schätzen, aber mehr eben nicht.

Aber Danke für den Hinweis
 

FArt

Top Contributor
Bei der Semaphorenimplementierung hier wartet nur der Consumer, und zwar bis es etwas zu tun gibt. Der Producer kommt sofort zurück.
Den Link findet man, wenn man sinnvolle Suchbegriffe hat (Semaphore z.B.) und das mit Begriffen wie java und tutorial verbindet.
Sonst: mal stöbern, was Oracle so alles an Tutorials, Dokus und technischen Artikeln so bietet.
 

andiv

Bekanntes Mitglied
Genaugenommen brauchst du die Größenbeschränkung der Queue hier gar nicht, aber sie kann nützlich sein wenn man will dass der Aufgabenberg eine bestimmte Größe nicht überschreitet. Auch den ExecutorService brauchst du hier nicht unbedingt, man hätte genauso gut von Hand zwei Threads erstellen können. Aber so hast du wenigstens mal gesehen wie man die verschiedenen Klassen bei einem Producer-Consumer-Problem anwenden kann.

Was Literatur angeht kann ich allgemein zu fortgeschrittenen Java-Themen "Effective Java" und zu Multithreading "Java Concurrency in Practice" empfehlen.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
B Threads Problem mit mehreren Threads Java Basics - Anfänger-Themen 38
L Zeit stoppen in mehreren Threads Java Basics - Anfänger-Themen 2
G [Threads]: Mit mehreren Threads 1 ArrayList durchlaufen Java Basics - Anfänger-Themen 19
F aus mehreren Programmen ein Programm mit Threads machen Java Basics - Anfänger-Themen 7
G Problem mit mehreren Threads und Buttons Java Basics - Anfänger-Themen 3
U Funktionale Interfaces mit mehreren abstrakten Methoden? Java Basics - Anfänger-Themen 8
C Problem mit mehreren Methoden + Scanner Java Basics - Anfänger-Themen 5
Poppigescorn String mit mehreren Wörtern füllen? Java Basics - Anfänger-Themen 4
CptK Interface Functional interface mit mehreren Methoden Java Basics - Anfänger-Themen 6
P Objekt in mehreren Methoden verwenden. Java Basics - Anfänger-Themen 3
freudianslip if-Statement mit mehreren Zahlenwerten Java Basics - Anfänger-Themen 4
B Zeitgleiches Arbeiten am Code mit mehreren Personen? Java Basics - Anfänger-Themen 7
M Arrays mit mehreren Werten über JOptionPane initialisieren Java Basics - Anfänger-Themen 12
S Und-Abfrage mit mehreren Ungleich-Operatoren Java Basics - Anfänger-Themen 17
D Aufruf von mehreren Activities bringt die app zum Absturz Java Basics - Anfänger-Themen 5
G String mit mehreren Attributen aufteilen Java Basics - Anfänger-Themen 6
B Funktion mit mehreren Rückgabewerten aka Prozeduren? Java Basics - Anfänger-Themen 12
L Wie geht man bei mehreren Action Klassen vor? Java Basics - Anfänger-Themen 0
O compareTo nach mehreren Kriterien Java Basics - Anfänger-Themen 13
B Java Mail: suchen von mehreren Emailadressen Java Basics - Anfänger-Themen 5
R Antwort vom Server an mehreren Clients senden Java Basics - Anfänger-Themen 3
G Refactoring von mehreren identischen Klassen Java Basics - Anfänger-Themen 36
K Geburtsdaten von Mehreren Personen speichern und Alter ausgeben Java Basics - Anfänger-Themen 11
T Interface Methode im Interface mit mehreren Parametern Java Basics - Anfänger-Themen 10
F Problem beim entfernen von mehreren Listenelementen auf einmal (Programmierung des Spiels Arschloch) Java Basics - Anfänger-Themen 1
S boolean Wert von mehreren int Möglichkeiten abfragen ? Java Basics - Anfänger-Themen 4
E if-Bedingung mit mehreren Möglichkeiten ? Java Basics - Anfänger-Themen 6
B MVC Struktur mit mehreren Szenen - wer schaut mal bitte drüber? Java Basics - Anfänger-Themen 2
A String mit mehreren Zeilen splitten Java Basics - Anfänger-Themen 4
U Schleife mit mehreren Bedingungen ? Java Basics - Anfänger-Themen 29
C OOP Von mehreren Klassen aus auf das selbe Objekt zugreifen Java Basics - Anfänger-Themen 8
M Erste Schritte Speichern von mehreren Daten Java Basics - Anfänger-Themen 3
B Variable in mehreren Klassen nutzen Java Basics - Anfänger-Themen 4
D Eine MySQL Verbindung in mehreren Klassen Java Basics - Anfänger-Themen 8
F Interface Nach mehreren Kriterien sortieren Java Basics - Anfänger-Themen 2
S OOP Variablen zwischen mehreren Klassen Java Basics - Anfänger-Themen 11
F Http Post von mehreren Daten Java Basics - Anfänger-Themen 5
Dechasa Interface JFrame mit mehreren Übereinander liegenden JPanel Java Basics - Anfänger-Themen 5
R Eine Datei mit mehreren Zeilen beschreiben Java Basics - Anfänger-Themen 5
S PHP Aufruf mit mehreren Variablen Java Basics - Anfänger-Themen 2
H Klassen Auf eine Hashtable aus mehreren Klassen zugreifen Java Basics - Anfänger-Themen 12
N Aufgabe: Pizza Konstruktor mit mehreren beliebigen Durchmesser/Preiskombinationen Java Basics - Anfänger-Themen 8
R Objekt erstellen - Attribute mit mehreren Werten Java Basics - Anfänger-Themen 1
F Selben Code in mehreren Projekten Java Basics - Anfänger-Themen 1
I Listen sortieren bei mehreren Listen zu einer Java Basics - Anfänger-Themen 2
M JUnit Testmethoden mit mehreren assert Methoden Java Basics - Anfänger-Themen 1
G Klassen Problem mit mehreren Klassen Java Basics - Anfänger-Themen 2
kaoZ Input/Output Android : Deserialisieren von mehreren Objekten in einer Datei Java Basics - Anfänger-Themen 0
J Menü mit mehreren Bildern Java Basics - Anfänger-Themen 5
kaoZ Input/Output Einlesen von mehreren Zeilen Java Basics - Anfänger-Themen 4
T Variablen Zufallsgenerator mit mehreren Variablen Java Basics - Anfänger-Themen 3
Devil0s Entwicklung mit mehreren Leuten Java Basics - Anfänger-Themen 7
3 JLabel - Text in mehreren Zeilen zentrieren Java Basics - Anfänger-Themen 5
R Compiler-Fehler Auf selben Array in mehreren "cases" vom "Switch" zugreifen Java Basics - Anfänger-Themen 11
K Vererbung Methoden in klassen auslagern und in mehreren Klassen verfügbar machen Java Basics - Anfänger-Themen 8
D Eine Variable in mehreren "switch" Java Basics - Anfänger-Themen 24
P Liste in einer Klasse füllen und mehreren anderen Klassen lesend verwenden Java Basics - Anfänger-Themen 5
propra Objekte in mehreren Listen Java Basics - Anfänger-Themen 6
T GUI Prog. mit mehreren Klassen Java Basics - Anfänger-Themen 4
K Erste Schritte Eingabetext besteht aus mehreren Zeilen? Java Basics - Anfänger-Themen 3
D javac zum Kompilieren von mehreren Dateien Java Basics - Anfänger-Themen 6
P Auslesen von mehreren XML Dateien - Fehler Java Basics - Anfänger-Themen 11
M Java Berechnung mit mehreren Lösungen? Java Basics - Anfänger-Themen 9
T List mit mehreren gleichen Strings bereinigen Java Basics - Anfänger-Themen 4
firefexx Input/Output close() bei mehreren Streams Java Basics - Anfänger-Themen 5
L Server mit mehreren Clients Java Basics - Anfänger-Themen 25
C Methoden Methoden mit mehreren Rückgabewerten Java Basics - Anfänger-Themen 11
D OOP Objekt in mehreren Objekten Java Basics - Anfänger-Themen 3
T Hashmap mit mehreren Werten Java Basics - Anfänger-Themen 9
M Backslash aus mehreren einen machen? Java Basics - Anfänger-Themen 7
M Frame mit mehreren areas Java Basics - Anfänger-Themen 14
Dit_ Aktualisieren von mehreren Views Java Basics - Anfänger-Themen 2
S Datentypen In mehreren Dateien Strings ersetzen Java Basics - Anfänger-Themen 14
B Swing Applikation mit mehreren Klassen Java Basics - Anfänger-Themen 2
J Matheaufgabe aus String mit mehreren Operatoren Java Basics - Anfänger-Themen 16
Q If-Abfrage mit mehreren Bedingungen Java Basics - Anfänger-Themen 6
D Datentypen Aufzählunsdatentyp in mehreren Klassen verwenden? Java Basics - Anfänger-Themen 10
U Umsetzungsfrage: Personen mit mehreren "Rollen" Java Basics - Anfänger-Themen 9
D Datentypen Liste mit Objekten aus mehreren Klassen Java Basics - Anfänger-Themen 3
P Doppelte Einträge in mehreren Textfiles finden und ausgeben Java Basics - Anfänger-Themen 8
M String mit mehreren Zahlen in Integer-Array Java Basics - Anfänger-Themen 2
S Infos aus mehreren JVMS verbinden Java Basics - Anfänger-Themen 3
ModellbahnerTT Klassen in mehreren Projekten benutzten Java Basics - Anfänger-Themen 3
J Performance Vergleich von if-Abfragen mit mehreren Bedingungen Java Basics - Anfänger-Themen 9
B Identifikation eines einzelnen Buttons aus mehreren Buttons per Schleife erzeugten Java Basics - Anfänger-Themen 4
M property mit mehreren werten Java Basics - Anfänger-Themen 3
H Vergleichen mit mehreren Textdateien Java Basics - Anfänger-Themen 2
X Konfiguration einer Anwendung aus mehreren Dateien Java Basics - Anfänger-Themen 11
K Rekusion bei Bäumen mit mehreren Blättern Java Basics - Anfänger-Themen 7
G Sortieren von mehreren klassen Java Basics - Anfänger-Themen 7
-horn- EINE setter/getter klasse aus mehreren klassen befüllen Java Basics - Anfänger-Themen 13
G art hashmap mit mehreren werten pro key Java Basics - Anfänger-Themen 2
C Programm mit mehreren Dateien Java Basics - Anfänger-Themen 2
V Screenshot von mehreren Monitoren machen Java Basics - Anfänger-Themen 6
S equals( mit mehreren möglichkeiten) Java Basics - Anfänger-Themen 18
P JTree mit mehreren Wurzeln Java Basics - Anfänger-Themen 2
B Kürzesten Weg zwischen mehreren Punkten finden (rekursiv) Java Basics - Anfänger-Themen 5
H Ein Hauptprogramm mit mehreren Fenstern . Java Basics - Anfänger-Themen 6
M Kann man im Filter nach mehreren Strings filtern lassen Java Basics - Anfänger-Themen 11
E ArrayList mit mehreren Werten Java Basics - Anfänger-Themen 10

Ähnliche Java Themen

Neue Themen


Oben