Mehrere Threads nutzen --> run() schneller als start(), Warum?

Milo

Bekanntes Mitglied
Hallo,

ich experimentiere gerade ein wenig mit Threads. Hierzu gebe ich jedem Thread die Referenz eines Objektes mit. Innerhalb der Threads wird eine Berechnung durchgeführt. Ist das Ergebnis der einzelnen Berechnung besser, als das bisherige, dann speichere ich die "neu" Lösung in diesem Objekt. Über synchronized sollte, wenn ich es richtig verstanden habe, verhindert weden, dass zwei Threads gleichzeitig speichern - ist das korrekt so?

Java:
public class Result {
	private double d = Double.MAX_VALUE;
	private double par[];
	
	public synchronized void setValues(double d, double par[]) {
		if (d <= this.d) {
			this.d = d;
			this.par = par;
		}
	}
}

Da ich das Ende des am längsten laufenden Thread abwarten muss, rufe ich join bei allen Threads auf. Vereinfacht sieht das ganze wie folgt aus, wobei tasks eine Liste mit allen Threads ist.

Java:
for (Thread task : tasks) {
	task.start();
}
for (Thread task : tasks) {
	try {
		task.join();
	} catch (InterruptedException e) {
		e.printStackTrace();
	}
}

Was mich nun wundert ist, dass wenn ich task.start(); durch task.run(); ersetze (und somit nicht mehr mehrere Thread gleichzeitig arbeiten) die Berechnung um ca. die Hälfte schneller ist. Sollte das nicht genau andersherum ablaufen?

Freue mich, wenn Ihr mir ein paar Tipps geben könntet.

Micha
 
Für diesen Aufbau könntest du dir auch Callable angucken. Ist hier, imho, etwas passender.
Wie groß sind denn die Zeiten? Mit "Hälfte schneller" könnte auch der Unterschied zwischen 1ms und 2ms heißen.
 
Ganz einfach: Der ganze Vewaltungsaufwand, der mit den Taskwechseln verbunden ist, fällt weg, und niemand muss in der Schlange stehen, weil gerade jemand anders im synchronisierten Klohäuschen sitzt. Für zu kleine Arbeitspakete und viele Threads ist Multithreading einfach Overkill. Je länger die Aufgaben sind, und je weniger die Threads miteinander zu tun haben, um so mehr lohnt es sich performancemäßig (mehrere Cores einmal vorausgesetzt). Natürlich hilft Multithreading auch, wenn "Gleichzeitigkeit" gefragt ist, z.B. wenn man eine GUI haben will, die nicht andauernd einfriert. Aber reich rechnerisch wird das System dadurch meist langsamer.
 
Zuletzt bearbeitet:
Hallo,

Ganz einfach: Der ganze Vewaltungsaufwand, der mit den Taskwechseln verbunden ist, fällt weg
Ah, Danke. Das kann ich, nachdem ich die Berechnungszeit mal künstlich verlängert habe, bestätigen. Die einzelnen Teilrechnungen sind so schnell fertig, das wohl genau das von Dir beschriebene eintritt.

Der Unterschied lag bei ca. 5 zu 12 Sekunden, wobei extrem viele kurze Berechnungen gestartet werden.

Erstmal vielen Dank für Eure schnellen Antworten!

Micha
 

Zurück
Oben