Multi Threaded Version langsamer als normale Version

Sophie

Bekanntes Mitglied
Hallo Zusammen

Ich versuche gerade eine Lineare Suche mit Threads zu beschleunigen. Leider dauert meine Suche mit Threads wesentlich länger als ohne. Ich habe mit einer Arraylänge von 10000000 getestet, und das Array in unterschiedlich große Teile zerteil, die besten Ergebnise (aber immernoch ziemlich schlecht) habe ich mit 10000 teilen, also 1000 Threads erhalten. Was mir viel zu viel erscheint.
Könnt Ihr mir vielleicht sagen, was ich bei meiner Testklasse falsch mache?

Java:
public static void main(String[] args) {

		long starten = System.currentTimeMillis();
		int tNumber = 0;
		int slize = 100;// Variable which is the size of the parts in which the
						// array will be splitted
		int temp = slize;
		
		// Array Size and Search Key will be given as an argument
		int[] arr = new int[Integer.parseInt(args[0])]; 
		int searchKey = 6000;//Integer.parseInt(args[1]);
		Thread[] ts;

		// fills Array arr with Integers
		for (int j = 0; j < arr.length; j++) {
			arr[j] = j;
		}

		// Splitting the Array
		if (arr.length < slize) {
			problem2.LinearSearch ls = new problem2.LinearSearch(arr, 0, arr.length, searchKey,
					slize, starten);
			ls.run();
		} else {
			for (int i = 0; i < Integer.parseInt(args[0]); i++) {
				if (i > temp) {
					tNumber++;
					temp = temp + slize;
				}
			}
		}

		ts = new Thread[tNumber];

		// Creates Threads
		for (int j = 0; j < tNumber; j++) {

			int start = slize * j; // calculation start and end of each Array
			int end = slize * (j + 1);

			if (j == tNumber)
				end = arr.length;
			ts[j] = new Thread(new problem2.LinearSearch(arr, start, end, searchKey,
					slize, starten));
			ts[j].setName(Integer.toString(j));
		}

		// Starts the Threads
		for (int k = 0; k < tNumber; k++) {
			ts[k].start();
			try {
				ts[k].join();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}
 

Marco13

Top Contributor
1000 Threads sind SO viel zu viel, dass es schon fast seltsam ist, dass es ihn da nicht raushaut. Für detailliertere Infos bräuchte man mehr Code, speziell eben die LinearSearch-Klasse. Aber beim ersten überfliegen sieht der Code ein bißchen chaotisch und schwer durchschaubar aus (dort steht an einer stelle run() - sicher dass das stimmt?) und insbesondere denke ich, dass die Threads ERST alle gestartet und DANN alle gejoint werden sollten... Kannst dich aber auch mal im Package java.util.concurrent umsehen, oder was das Fork-Join-Framework aus Java 7 so alles bringt (geht genau in diese Richtung)
 

Sophie

Bekanntes Mitglied
Hallo Marco

Das mit join() hab ich schonmal geändert, also eine extra Schleife gemacht, ändert aber noch nichts am Ergebnis.

Das mit dem run() ist wahrscheinlich nicht so ganz üblich, aber ich dachte mir, wenn das Array klein genug ist, kann eine Lineare Suche ohne Threads gemacht werden und deshalb starte ich die dann ganz normal.

Das hier ist meine suche, ich habe gerade noch etwas abgeändert und die Zeile

Java:
		if (searchKey > end) {
			Thread.currentThread().interrupt();
		}

eingefügt, was bezwecken soll, dass wenn die gesuchte Zahl größer als das Ende des Arrays ist, der Thread blockiert wird. Das bringt aber auch nix

Java:
@Override
	public void run() {

		// Empty Array
		if (arr.length == 0) {
			System.out.println("Empty");
			System.exit(0);
		}

		if (searchKey > end) {
			Thread.currentThread().interrupt();
		}

		// As long as not found
		if (done == false) {
			for (int i = start; i < end; i++) {

				if (arr[i] == searchKey) {
					for (int j = 0; j < arr.length; j++) {
						if (arr.length > slice) {
							// Prints result
							int id = Integer.parseInt(Thread.currentThread()
									.getName());
							System.out.println("Thread: " + id + "     "
									+ "Position: " + i);
							long stop = System.currentTimeMillis();
							System.out.println(stop - starten);
							done = true;
							System.exit(0);
						}
					}
				}
			}
		} else {
			start++;
			run();
		}

	}
 

Marco13

Top Contributor
Ja sicher, ab einer bestimmten Größe (bzw. Kleine) sollte man die "normale" Lineare Suche machen. Aber wie genau die Abläufe dort im Moment sind, wird aus dem geposteten (für mich) nicht direkt ersichtlich. Kannst du das ganze mal als KSKB zusammenkopieren, so dass man es direkt compilieren und starten kann?
 

Sophie

Bekanntes Mitglied
Sorry, ich weiss nicht, was Du mit KSKB meinst

Hier mal der komplette Code

Java:
/**
 * Searches given search Key in Array
 */

public class LinearSearch implements Runnable {

	int[] arr;
	int searchKey;
	int start;
	int end;
	boolean done = false;
	int slice;
	long starten;

	/**
	 * Constructor
	 * 
	 * @param arr
	 * @param start
	 * @param end
	 * @param digit
	 * @param slize
	 */
	public LinearSearch(int[] arr, int start, int end, int digit, int slize,
			long starten) {
		super();
		this.arr = arr;
		this.searchKey = digit;
		this.start = start;
		this.end = end;
		this.slice = slize;
		this.starten = starten;
	}

	/**
	 * Searches the key
	 */
	@Override
	public void run() {

		// Empty Array
		if (arr.length == 0) {
			System.out.println("Empty");
			System.exit(0);
		}

		if (searchKey > end) {
			Thread.currentThread().interrupt();
		}

		// As long as not found
		if (done == false) {
			for (int i = start; i < end; i++) {

				if (arr[i] == searchKey) {
					for (int j = 0; j < arr.length; j++) {
						if (arr.length > slice) {
							// Prints result
							int id = Integer.parseInt(Thread.currentThread()
									.getName());
							System.out.println("Thread: " + id + "     "
									+ "Position: " + i);
							long stop = System.currentTimeMillis();
							System.out.println(stop - starten);
							done = true;
							System.exit(0);
						}
					}
				}
			}
		} else {
			start++;
			run();
		}

	}

}

Java:
/**
 * Tests LinearSearch Class
 */

public class LinearSearchTest {

	public static void main(String[] args) {

		long starten = System.currentTimeMillis();
		int tNumber = 0;
		int slize = 10000;// Variable which is the size of the parts in which
							// the
							// array will be splitted
		int temp = slize;

		// Array Size and Search Key will be given as an argument
		int[] arr = new int[Integer.parseInt(args[0])];
		int searchKey = 9999990;// Integer.parseInt(args[1]);
		Thread[] ts;

		// fills Array arr with Integers
		for (int j = 0; j < arr.length; j++) {
			arr[j] = j;
		}

		// Splitting the Array
		if (arr.length < slize) {
			problem2.LinearSearch ls = new problem2.LinearSearch(arr, 0,
					arr.length, searchKey, slize, starten);
			ls.run();
		} else {
			for (int i = 0; i < Integer.parseInt(args[0]); i++) {
				if (i > temp) {
					tNumber++;
					temp = temp + slize;
				}
			}
		}

		ts = new Thread[tNumber];

		// Creates Threads
		for (int j = 0; j < tNumber; j++) {

			int start = slize * j; // calculation start and end of each Array
			int end = slize * (j + 1);

			if (j == tNumber)
				end = arr.length;
			ts[j] = new Thread(new problem2.LinearSearch(arr, start, end,
					searchKey, slize, starten));
			ts[j].setName(Integer.toString(j));
		}

		// Starts the Threads
		for (int k = 0; k < tNumber; k++) {
			ts[k].start();
			// try {
			// ts[k].join();
			// } catch (InterruptedException e) {
			// e.printStackTrace();
			// }
		}
		for (int k = 0; k < tNumber; k++) {
			try {
				ts[k].join();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}
 

faetzminator

Gesperrter Benutzer
Ohne alles im Detail gelesen zu haben: es klingt für mich danach, dass du mit einem Thread Pool arbeiten willst. da gibt es [japi]ThreadPoolExecutor[/japi], bei welchem du angeben kannst, wie viele Threads du willst und danach alle Arbeiten in eine Queue stellen kannst. Für Berechnungen benötigst du eigentlich nicht mehr Threads als du CPU-Kerne besitzt. Diese kannst du mit Runtime (Java Platform SE 6) auslesen.
 

Marco13

Top Contributor
Ja, ein ThreadPool wäre da sicher sinnvoller. Ich gehe im Moment noch davon aus, dass das ganze zu Fuß implementiert werden soll.

So ganz sind mir aber einige Teile nicht klar. Z.B. der Teil mit
Java:
for (int j = 0; j < arr.length; j++) {
     if (arr.length > slice) {

Insgesamt solltest du versuchen, nicht so viele Annahmen und Abfragen und Sonderfälle zu verwenden. Bei allgemeiner Beschreibung sollte das zumindest nicht nötig sein.

Speziell das
Java:
if (searchKey > end) {
    Thread.currentThread().interrupt();
}
ist ja schon ein (sinnloser) "cheat" : Das macht nur Sinn, wenn die Array-Elemente wirklich von 0 bis n durchnummeriert sind. Bei zufällger Reihenfolge würde das ja nicht funktionieren. Und selbst wenn: Man sollte dann den Thread eher gar nicht starten statt ihn sofort nach dem Start zu unterbrechen ;)

Bei den Arraygrenzen hat was noch nicht ganz gestimmt. Wenn man das gepostete mit einen 10000000-Array startet, fehlt das letzte Segment (d.h. 9999990 wird nicht gefunden).

Das mit dem System.exit ist eigentlich bogus, aber war wohl nur zum Testen drin ;)

Die Zeitmessungen sind auch höchst fragwürdig: Die Zeitmessung schleißt ja das Erstellen und Füllen des Arrays mit ein. Das sollte man von der eigentlichen Suche (die man ja schneller machen will) trennen.

Bei sowas wie
Java:
for (int i = 0; i < Integer.parseInt(args[0]); i++) {
wird etliche tausend mal ein Integer geparst. Das kostet enorm viel Zeit, und verfälscht das Ergebnis noch mehr. Nur weil es einfach ist, das so hinzuschreiben, sollte man es doch nicht tun, und stattdessen so selten wie möglich parsen.

Du kannst ja mal versuchen, das ganze stärker zu trennen, und nicht so sehr solche Dinge wie Zeitmessungen, Setup und Ausgaben zu vermischen. Zum Beispiel (!) indem du versuchst, hier bei "TODO" eine aufgeräumtere Version dessen einzufügen, was bisher in der main() stand:
Java:
/**
 * Tests LinearSearch Class
 */

public class LinearSearchTest {

    public static void main(String[] args) {

        // Array Size and Search Key will be given as an argument
        int arraySize = 10000000;
        int searchKey =  9999990;// Integer.parseInt(args[1]);

        // fills Array arr with Integers
        int[] arr = new int[arraySize];
        for (int j = 0; j < arr.length; j++) {
            arr[j] = j;
        }

        testSearchSingle(arr, searchKey);
        testSearchMulti(arr, searchKey, 10);
    }


    private static void testSearchSingle(int array[], int key)
    {
        long before = System.nanoTime();
        int index = searchSingle(array, key);
        long after = System.nanoTime();
        System.out.println("searchSingle found "+index+" took "+(after-before)/1e6+" ms");
    }


    /**
     * Returns the index of the key inside the array,
     * or -1 if the key is not found
     */
    private static int searchSingle(int array[], int key)
    {
        for (int i=0; i<array.length; i++)
        {
            if (array[i] == key)
            {
                return i;
            }
        }
        return -1;
    }


    private static void testSearchMulti(int array[], int key, int numThreads)
    {
        long before = System.nanoTime();
        int index = searchMulti(array, key, numThreads);
        long after = System.nanoTime();
        System.out.println("searchMulti  found "+index+" took "+(after-before)/1e6+" ms");
    }

    private static int searchMulti(int array[], int key, int numThreads)
    {
        // TODO: Implement
        return -1;
    }
}
 

Sophie

Bekanntes Mitglied
Ohne alles im Detail gelesen zu haben: es klingt für mich danach, dass du mit einem Thread Pool arbeiten willst. da gibt es [japi]ThreadPoolExecutor[/japi], bei welchem du angeben kannst, wie viele Threads du willst und danach alle Arbeiten in eine Queue stellen kannst. Für Berechnungen benötigst du eigentlich nicht mehr Threads als du CPU-Kerne besitzt. Diese kannst du mit Runtime (Java Platform SE 6) auslesen.

Hallo faetzminator

Ist ein ThreadPool nicht dazu gedacht einen Overhead zu vermeiden?
Das mache ich bei meiner Version selbts, indem ich die Größe bestimme, in welche das Array aufgeteilt wird.
Oder hat ein ThreadPool auch noch andere Funktionen, die mir hier helfen könnent=
 

faetzminator

Gesperrter Benutzer
Ein weiterer Grund wär da z.B., dass Threads wiederverwendet werden. Dies ist sinnvoll, da das Erstellen eines Threads viel Zeit benötigt. Und du musst es nicht selbst verwalten.
 

Sophie

Bekanntes Mitglied
aber brauche ich das denn hier? ich schick ja die Threads drauf, wenn ein Thread einen Abschnitt hat, in dem die gesuchte Zahl nicht enthalten ist, brauch ich ihn nicht mehr. Und der Thread der den Abschnitt hat arbeitet dann weiter.

(ich möchte nicht Deine Antwort in Frage stellen, ich frage nur nach, weil ich nicht verstehe wie mir hier ein Threadpool weiterhelfen kann)
 

tuttle64

Bekanntes Mitglied
Hallo Sophie

In den Klassen Arrays und Collections befindet sich eine Unmenge von Methoden für die Speicherung und das Suchen von Elementen. So erinnert mich die Methode testSearchSingle() an die Arrays-Methode binarySearch(). Weshalb verwendest Du nicht binarySearch()?
 

Sophie

Bekanntes Mitglied
Weil es in dieser Aufgabe nicht um die Suche geht (die funktioniert ja) sondern um die Threads. Eine binäre Suche ist für Threads ungeeignet, so weit ich weiss.
Collections sollen wir hier nicht benutzen
 

tuttle64

Bekanntes Mitglied
Ok, wenn eine lineare Suche nicht optimal implementiert ist resp. deine Maschine lahm ist, wird diese mit Threads auch nicht schneller. Aus einem VW Polo kannst Du auch keinen Ferrari machen.
 
M

Marcinek

Gast
Du hast zuviele Threads, die gleichzeitig laufen. Die Verwaltung der Threads. Erstellen, ausführen, löschen ist ein ernormer Overhead zu der Suche in der Liste. Dann Zeitscheiben des Prozessors, in denen ein Thread gerade ausgeführt werden kann und und und. ..

Ein Threadpool erzeugt x Threads ( 10 oder 20) und wenn die Aufgebraucht sind, dann werden keine neuen Aufgaben angenommen oder neue Threads erzeugt.

Wenn die optimierung der Geschwindigkeit in der Erhöhung von Threads liegen würde, dann wäre NP = P ;). Außerdem würde es Informatiker erübrigen, da dann jeder iwas programmieren könnte und es wäre effizient solange genug Threads da sind....
 

hdi

Top Contributor
@Sophie

Um die Performance bei Multi-Threading ordentlich testen zu können, musst du den Test auf deine Testumgebung anpassen. D.h.: Maximal soviele Threads, wie dein Prozessor Kerne hat. Alles darüber ist nämlich kontraproduktiv für die Performance. Wenn du nen Dualcore Prozessor hast dann wird deine Suche mit 50 Threads kein Deut schneller sein als mit 2 Threads. Wie gesagt, eher noch langsamer.

Also mach erstmal sinnige Tests, um herauszufinden ob der Code passt oder nicht. Führ's aus mit 1 Thread und stopp die Zeit. Führ's aus mit 2 Threads und stopp die Zeit. Wenn du das gut implementiert hast und die Arbeit gleichmäßig verteilt, soltle sich die Zeit in etwa halbieren. Natürlich nur, wenn du auch 2 Kerne hast. Und erhöh die Anzahl der Threads Stück für Stück bis du deinen Prozessor voll auslastet, d.h. Anzahl Threads = Anzahl Kerne.

Anhand dieser Testergebnisse kann man dann feststellen, inwiefern die Implementierung passt oder nicht.
 

Sophie

Bekanntes Mitglied
Hallo Marcinek

Ja, ich habe aber das gleiche Program aber auch mit nur 8 Threads ausgeführt, und ich hatte in etwa das gleiche Ergebnis (war sogar noch etwas langsamer) deshalb denke ich eher, dass das Problem nicht bei der Anzahl der Threads liegt, sondern dass der Code für meine lineare Suche unbrauchbar für Threads ist. Ich weiss aber nicht, was ich ändern könnte
 

Sophie

Bekanntes Mitglied
@Sophie

Um die Performance bei Multi-Threading ordentlich testen zu können, musst du den Test auf deine Testumgebung anpassen. D.h.: Maximal soviele Threads, wie dein Prozessor Kerne hat. Alles darüber ist nämlich kontraproduktiv für die Performance. Wenn du nen Dualcore Prozessor hast dann wird deine Suche mit 50 Threads kein Deut schneller sein als mit 2 Threads. Wie gesagt, eher noch langsamer.

Also mach erstmal sinnige Tests, um herauszufinden ob der Code passt oder nicht. Führ's aus mit 1 Thread und stopp die Zeit. Führ's aus mit 2 Threads und stopp die Zeit. Wenn du das gut implementiert hast und die Arbeit gleichmäßig verteilt, soltle sich die Zeit in etwa halbieren. Natürlich nur, wenn du auch 2 Kerne hast. Und erhöh die Anzahl der Threads Stück für Stück bis du deinen Prozessor voll auslastet, d.h. Anzahl Threads = Anzahl Kerne.

Anhand dieser Testergebnisse kann man dann feststellen, inwiefern die Implementierung passt oder nicht.

Das wären dann 8 bei mir, wenn ich dann ein Array der Größe 10.000.000 nehme und es dann in acht Teile zerlege, also jeweils mit 1250000 Elementen. Dann komm ich ohne Threads auf 26 Millisekunden und mit Threads auf 507 Millisekunden.
Das Ergebnis sollte nicht so aussehen, oder?
 

hdi

Top Contributor
Ach, 1 Thread braucht 26ms? Na dann wundert's nicht.. Der Wert ist so winzig, da steht das alles in keinem Verhältnis. Klar, dass der Overhead in so einem Fall schon größer ist als die eigentliche Berechnung. Du hast einfach einen Usecase, für den Multi-Threading keinen Sinn macht. Ab 500ms können wir darüber reden, ob Multi-Threading Sinn macht. Aber dann auch nur 2 bis max 3 Threads. Normalerweise wendet man MT für Performance-Optimierung an, um spürbar an Speed zuzulegen. 26ms ist sicherlich nicht spürbar.
 
M

Marcinek

Gast
m die Performance bei Multi-Threading ordentlich testen zu können, musst du den Test auf deine Testumgebung anpassen. D.h.: Maximal soviele Threads, wie dein Prozessor Kerne hat. Alles darüber ist nämlich kontraproduktiv für die Performance. Wenn du nen Dualcore Prozessor hast dann wird deine Suche mit 50 Threads kein Deut schneller sein als mit 2 Threads. Wie gesagt, eher noch langsamer.

Das ist so nicht korrekt. Auch bei mehr Threads als Kernen kann die Performance dann steigern, wenn Operationen lange wartezeiten auf andere Ressourcen haben.

Also wenn viele blockierende Aktionen habe, dann kann ich währenddessen andere machen, die nicht blockiert sind. ;)


...

@TO: Doch genau so soll es sein. Mehr Threads bedeutet nicht schneller.
 

Sophie

Bekanntes Mitglied
Ach, 1 Thread braucht 26ms? Na dann wundert's nicht.. Der Wert ist so winzig, da steht das alles in keinem Verhältnis. Klar, dass der Overhead in so einem Fall schon größer ist als die eigentliche Berechnung. Du hast einfach einen Usecase, für den Multi-Threading keinen Sinn macht. Ab 500ms können wir darüber reden, ob Multi-Threading Sinn macht. Aber dann auch nur 2 bis max 3 Threads. Normalerweise wendet man MT für Performance-Optimierung an, um spürbar an Speed zuzulegen. 26ms ist sicherlich nicht spürbar.

Ok, also meinen PC noch mehr quälen und einfach das Array vergrößern?
 

hdi

Top Contributor
Das ist so nicht korrekt. Auch bei mehr Threads als Kernen kann die Performance dann steigern, wenn Operationen lange wartezeiten auf andere Ressourcen haben.
Stimmt, ich hab mich mit meiner Aussage auf ihren konkreten Anwendungsfall bezogen. Sie hat ja keine Wartezeiten, ihre Threads rennen durch.

@TO:
Hier mal ein sinnvolles Beispiel von Performance-GEwinn durch MT:

Java:
import java.math.BigInteger;

/** @author [url=http://www.javavideokurs.de]Java Video Kurs - Java Video Tutorials - Online Java lernen![/url] */

public class Summe implements Runnable {

	/*
	 * Jeder Thread kümmert sich nur um die Aufsummierung eines bestimmten
	 * Teilintervalls aus der Gesamt-Summierung:
	 */
	private long von;
	private long bis;

	/* Um Überlaufe zu vermeiden, benötigen wir hier natürlich auch BigInteger */
	private BigInteger ergebnis = BigInteger.ZERO;

	/*
	 * Flag, um der berechneSumme()-Methode mitzuteilen, ob die Berechnung
	 * vollendet ist
	 */
	private boolean fertig = false;

	public Summe(long von, long bis) {
		this.von = von;
		this.bis = bis;
	}

	@Override
	public void run() {
		/* Wie gehabt ein einfaches iteratives Aufsummieren des Ergebnisses */
		while (von >= bis) {
			ergebnis = ergebnis.add(new BigInteger(von + ""));
			von--;
		}
		
		/* Setze Flag */
		fertig = true;
		
		/* Benachrichtige berechneSumme() darüber, dass der Thread fertig ist */
		synchronized (this) {
			notifyAll();
		}
	}

	public boolean isFertig() {
		return fertig;
	}

	public BigInteger getErgebnis() {
		return ergebnis;
	}

	public static BigInteger berechneSumme(long zahl, int threads) {

		/* Prüfe Argumente... */
		if (zahl < 1) {
			throw new IllegalArgumentException("Ungültige Zahl: " + zahl);
		}
		if (threads < 1) {
			throw new IllegalArgumentException("Ungültige Thread-Anzahl: "
					+ threads);
		}
		if (threads > zahl) {
			throw new IllegalArgumentException(
					"Anzahl der Threads übersteigt den Wert der Zahl!");
		}

		/*
		 * Berechne die Intervall-Größe, die jeder Thread aufsummieren muss, um
		 * den Berechnungs-Aufwand fair zwischen allen Threads zu verteilen:
		 */
		long intervall = zahl / threads;
		/*
		 * Beachte, dass die Division nicht aufgehen muss. Den Rest dürfen wir
		 * nicht vernachlässigen:
		 */
		long rest = zahl % threads;

		/*
		 * Erzeuge die Instanzen für die einzelnen Threads, wobei jeder Thread
		 * ein Intervall aus der nötigen Gesamt-Summierung erhält:
		 */
		Summe[] threadArray = new Summe[threads];
		long von = 0;
		long bis = 0;
		for (int i = 0; i < threads; i++) {
			if (i == 0) {
				/*
				 * Der erste Thread berechnet auch das, was bei der Aufteilung
				 * eventuell übrig bleibt, weil es nicht aufgeht
				 */
				von = zahl;
				bis = zahl - intervall + 1;
				bis -= rest;
			} else {
				/*
				 * Alle anderen berechnen das vorher berechnete Intervall - mit
				 * jeweils unterschiedlichem Anfangs- und Endwert
				 */
				von = bis - 1;
				bis = von - intervall + 1;
			}
			Summe sum = new Summe(von, bis);
			threadArray[i] = sum;
		}

		/* Starte Threads... */
		for (Summe sum : threadArray) {
			new Thread(sum).start();
		}

		/* Warte, bis alle Threads ihre Berechnungen durchgeführt haben */
		for (Summe sum : threadArray) {
			synchronized (sum) {
				while (!sum.isFertig()) {
					try {
						sum.wait();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}

		/* Summiere die einzelnen Ergebnisse, um das Endergebnis zu erhalten */
		BigInteger endErgebnis = BigInteger.ZERO;
		for (Summe sum : threadArray) {
			endErgebnis = endErgebnis.add(sum.getErgebnis());
		}
		return endErgebnis;
	}

}

Java:
import java.math.BigInteger;

/** @author [url=http://www.javavideokurs.de]Java Video Kurs - Java Video Tutorials - Online Java lernen![/url] */

public class SummeTest {

	// HIER ANZAHL DER KERNE DEINES PROZESSORS EINTRAGEN:
	private static final int MY_CORES = 8;

	public static void main(String[] args) {

		long zahl = 45190291L;
		for (int loop = 1; loop <= 10; loop++) {
			for (int threads = 1; threads <= MY_CORES; threads++) {
				test(zahl, threads);
			}
			System.out.println();
			zahl *= 2;
		}
	}

	private static void test(long zahl, int threads) {
		long start = System.currentTimeMillis();

		BigInteger ergebnis = Summe.berechneSumme(zahl, threads);

		long stop = System.currentTimeMillis();
		double zeit = (stop - start) / 1000.;

		System.out.println("Summe von " + zahl + " ist: " + ergebnis
				+ " (berechnet in " + zeit + " Sekunden von " + threads
				+ " Thread(s))");
	}
}

Es ist ein bisschen kompliziertes als es sein müsste, da es noch ein paar andere Dinge demonstrieren soll. Ist aber nicht so wichtig. Veränder mal in der Programm-Klasse den Wert von MY_CORES, erst 1 dann 2 hoch bis 8. Und schau dir die Ergebnisse an und kuckim Task Manager die CPU-Auslastung an. Hier bringt das ganze etwas, da es hier um eine große Aufgabe geht die ein Thread halt eben nicht mal eben in 26ms berechnen kann.
 

hdi

Top Contributor
Haben grad gleichzeitig geschrieben. Du kannst ja mal das Array mit Integer.MAX Länge machen. Mal kucken wie da die Werte aussehen. Ein anderes Bsp: siehe mein letzter Post.
 

Marco13

Top Contributor
@Sophie: Wie ich weiter oben schon ausführlich beschrieben habe, gab es an dem Programm einige Fragwürdigkeiten - und insbesondere die Zeitmessung war alles andere als sinnvoll....
 

Sophie

Bekanntes Mitglied
@Sophie: Wie ich weiter oben schon ausführlich beschrieben habe, gab es an dem Programm einige Fragwürdigkeiten - und insbesondere die Zeitmessung war alles andere als sinnvoll....

Oh je, das hab ich gar nicht gesehen, auch keine Benachrichtigung bekommen. Wahrscheinlich weil ich gerade geantwortet habe. Vielen Dank!


@hdi

Auch an Dich besten Dank!
Das schaut ja komplett anders aus :(

Dann werde ich jetzt nochmal versuchen was zu verbessern...
 

Marco13

Top Contributor
Das schaut ja komplett anders aus :(

Deswegen hatte ich anskizziert, wie es aussehen könnte, wenn man versuchen würde, noch einiges ("möglichst viel") von der bisherigen Struktur beizubehalten. Allerdings würde man es eigentlich vom Ansatz her schon etwas anders machen... Ich hatte ja schon auf das "System.exit" hingewiesen, was eigentlich ein no-go ist. Stattdessen muss man sich eben überlegen, WIE man WEM mitteilt, dass das Eregebnis gefunden wurde...
 

Sophie

Bekanntes Mitglied
Hallo jetzt funktioniert alles.

searchSingle took 10.0 ms
Result: 5632846
searchMulti took 1.0 ms
Result: 5632846

Die Größe des Arrays ist 100000000 und die Anzahl der Threads 8.

Das ist als Ergebnis ok, oder?

Vielen Dank für Eure Hilfe!
 

Marco13

Top Contributor
Das Ergebnis ist nicht die Ausgabe, sondern der Code, der die Ausgabe produziert.
Java:
class Multithreading
{
    public static void main(String args[])
    {
        System.out.println("searchSingle took 10.0 ms");
        System.out.println("Result: 5632846");
        System.out.println("searchMulti took 1.0 ms");
        System.out.println("Result: 5632846    ");
    }
}
:D
 

hdi

Top Contributor
Hehe... Ich glaube kaum dass sie sich selbst so betrügt :D

Aber wir sollten durchaus klären ob du die Zeit richtig misst.. Ist teilweise nämlich gar nicht so trivial. Und was du auch bedenken musst: Es gibt Schwankungen in der Performance, das ist normal, da noch viele externe Faktoren eine Rolle spielen (wie viele andere Prozesse laufen, tun sie grad zufällig etwas wenn dein Test läuft, wieviel "Glück" hat dein Prozess beim Scheduling, etc).

D.h. du solltest diesen Test jeweils mindestens 10 mal ausführen und ein Mittelwert nehmen. Wenn 1 Thread niemals unter 10ms kommt, und 8 immer deutlich unter 10ms sind, ja, dann kann davon ausgegangen werden dass due s richtig gemacht hast :)

Trotzmde würd ich's mit noch größeren Berechnugen testen.. Mach das ganze doch mal mit 100 Arrays á 10000000, bzw einfach ne Schleife die 100mal durchläuft. Und stopp die Zeit wielang dieThreads brauchen um das ganze 100x zu machen. Wenn dann rauskommt einer macht's in 1 Sekunde und 8 machen's in ~150ms, dann ist das noch aussagekräftiger. Je größer die Zeitwerte, desto größer auch die (absoluten) Zeitunterschiede, und desto begründeter kannst du das runterrechnen ob das jetzt in etwa 1/8tel der Zeit ist.
 
Zuletzt bearbeitet:

Sophie

Bekanntes Mitglied
Das Ergebnis ist nicht die Ausgabe, sondern der Code, der die Ausgabe produziert.
Java:
class Multithreading
{
    public static void main(String args[])
    {
        System.out.println("searchSingle took 10.0 ms");
        System.out.println("Result: 5632846");
        System.out.println("searchMulti took 1.0 ms");
        System.out.println("Result: 5632846    ");
    }
}
:D

Ganz schön frech! :D

Also die Zeit teste ich jeweils wie Marco vorgeschlagen hat

Java:
private static void testSearchSingle(int array[], int key) {
		long start = System.currentTimeMillis();
		int index = searchSingle(array, key);
		long stop = System.currentTimeMillis();
		double zeit = (stop - start);
		System.out.println("searchSingle took " + zeit + " ms" + "\n Result: "
				+ index);
	}

(Ich habe das auch mehrmal nacheinander ausprobiert und das Ergebnis, dass ich gepostet habe waren so die durchschnittlichen Werte)

Das mit mehreren Arrays werde ich auch noch ausprobieren, dauert noch nen Moment bis ich da Ergebnisse hab :)
 

hdi

Top Contributor
(Ich habe das auch mehrmal nacheinander ausprobiert und das Ergebnis, dass ich gepostet habe waren so die durchschnittlichen Werte)
Hm naja mehrmals gestartet? Weil das sagt nur teilweise etwas aus. Du musst daran denken dass die VM eventuell noch mit irgendwelchen Initialisierungen zu tun hat beim Start oder beim erstmaligen Aufruf einer Klasse/Methode. Es kann also sein dass methode1() grundsätzlich länger dauert als methode2(), weil in diesem Zuge Dinge getan werden müssen, die dann in methode2() nicht mehr getan werden müssen.

Deswegen solltest du den Mittelwert nicht nehmen von "mehrmals Programm gestartet", sondern von "mehrmals den Test gemacht" und zwar in einem einzigen Program-Run. Also pack das ganze eben in eine Schleife:

start time
50 x seachrsingle
stop time

start time
50 x searchmulti
stop time

Am besten die beiden Code-Blöcke auch mal vertauschen und erneut starten.
 

Sophie

Bekanntes Mitglied
Ok, hier sind die Ergebnisse

50 mal ausgeführt:
searchSingle took 161.0 ms
searchMulti took 57.0 ms

100 mal ausgeführt:
searchSingle took 309.0 ms
searchMulti took 1126.0 ms

100 mal ausgeführt, mit searchMulti angefangen
searchMulti took 1621.0 ms
searchSingle took 767.0 ms
(Hier habe ich sehr unterschiedliche Ergebnisse bekommen, meistens war searchMulti langsamer)

dann hab ich nochmal das gleiche ausprobiert mit nur 4 Threads
searchMulti took 262.0 ms
searchSingle took 1213.0 ms

und mit nur 2 Threads
searchMulti took 173.0 ms
searchSingle took 1901.0 ms


Kann man also allgemein sagen, dass wenn man die Anzahl der durchläufe erhöht sollte man die Anzahl der Threads verringern, da sonst wieder zu viele produziert werden?
 

hdi

Top Contributor
Kann man also allgemein sagen, dass wenn man die Anzahl der durchläufe erhöht sollte man die Anzahl der Threads verringern, da sonst wieder zu viele produziert werden?
Die Threads sollten sich ja automatisch beenden, wenn sie ihre Berechnung durchgeführt haben (Ende der run-Methode erreicht). Insofern sollte es egal sein ob 1 Durchlauf oder 500 Durchläufe, da ja am Ende eines Durchlaufs alle Threads weg sind und die nur paar neue machst, die dann wieder nach dem Durchgang weg sind, usw. D.h. du hast zu kienem Zeitpunkt mehr als 8 aktive Threads. Zumindest wenn du den Test jetzt nicht versemmelt hast. Natürlich musst du immer warten, bis ein Durchgang fertig ist... Schon klar?!

Diese neuen Messergebnisse zeigen deutlich dass du irgendwas doch noch nicht ganz richtig gemacht hast. Sie sind total widersprüchlich. Mit 8 Threads sollte immer etwa 8-mal so schnell gehen wie mit einem. Und auch das ist komisch:

und mit nur 2 Threads
searchMulti took 173.0 ms
searchSingle took 1901.0 ms

Kann nicht sein, dass 2 Threads mehr als 10x so schnell sind wie einer. Der Wert kann sich maximal halbieren.

Also irgendwas passt da nicht... Zeig ma deinen Code.
 

Sophie

Bekanntes Mitglied
Oh je, dass wird ja immer komplizierter

Java:
public class LineareSuche implements Runnable {

	int[] arr;
	int searchKey;
	int start;
	int end;
	static int index;
	boolean done = false;

	/**
	 * Constructor
	 * 
	 * @param arr
	 * @param start
	 * @param end
	 * @param digit
	 * @param slize
	 */
	public LineareSuche(int[] arr, int start, int end, int digit) {
		this.arr = arr;
		this.searchKey = digit;
		this.start = start;
		this.end = end;
	}

	/**
	 * Searches the key
	 */
	@Override
	public void run() {

		for (int i = start; i <= end; i++) {
			if (arr[i] == searchKey) {
				index = arr[i];
				done = true;
			}
			start++;
		}
	}

	/**
	 * Returns the index of the key inside the array, or -1 if the key is not
	 * found
	 */
	public static int searchSingle(int array[], int key) {
		for (int i = 0; i < array.length; i++) {
			if (array[i] == key) {
				return i;
			}
		}
		return -1;
	}

	public static int searchMulti(int array[], int key, int numThreads) {

		int intervall = array.length / numThreads;
		int rest = array.length % numThreads;

		int start = 0;
		int end = 0;

		Thread[] ts = new Thread[numThreads];

		// Creates Threads
		for (int j = 0; j < numThreads; j++) {

			if (j == 0) {
				start = 0;
				end = intervall + rest - 1;
			} else {
				start = end + 1;
				end = end + intervall;
			}
			ts[j] = new Thread(new LineareSuche(array, start, end, key));
		}

		// Starts the Threads
		for (int k = 0; k < numThreads; k++) {
			ts[k].start();
		}
		return index;
	}
}

Java:
public class LineareSucheTest {

	public static void main(String[] args) {

		// Array Size and Search Key will be given as an argument
		int arraySize = 100000000;
		int searchKey = 5632846;// Integer.parseInt(args[1]);

		// fills Array arr with Integers
		int[] arr = new int[arraySize];
		for (int j = 0; j < arr.length; j++) {
			arr[j] = j;
		}
	
		testSearchMulti(arr, searchKey, 4);
		testSearchSingle(arr, searchKey);
	}

	private static void testSearchSingle(int array[], int key) {
		long start = System.currentTimeMillis();
		for (int i = 0; i <= 150; i++) {
		int index = LineareSuche.searchSingle(array, key);
		}
		long stop = System.currentTimeMillis();
		double zeit = (stop - start);
		System.out.println("searchSingle took " + zeit + " ms");
	}

	private static void testSearchMulti(int array[], int key, int numThreads) {
		long start = System.currentTimeMillis();
		for (int i = 0; i <= 150; i++) {
		int index = LineareSuche.searchMulti(array, key, numThreads);
		}
		long stop = System.currentTimeMillis();
		double zeit = (stop - start);
		System.out.println("searchMulti took " + zeit + " ms");
	}

}
 

hdi

Top Contributor
Oh.. Du, wie soll ich sagen.. Das ist.. total falsch. :D

Das Problem ist, dass du überhaupt nicht wartest bis die Threads fertig sind. Die Methode returned sofort, also kein Wunder dass bei deinem ersten Test immer 1ms war. Und auch kein Wunder, dass das auf einmal 2 Sekunden dauert wenn du das in ne 100er Schleife packst. Denn dann erzeugst du tatsächlich 800 Threads.. Du musst die Threads mit deinem Methodenaufruf synchronisieren:

Java:
        // Starts the Threads
        for (int k = 0; k < numThreads; k++) {
            ts[k].start();
        }
        // -------------- HIER MUSST DU WARTEN BIS ALLE THREADS FERTIG SIND!!!!
        return index;

Im Moment ist also nur singleSearch richtig implementiert. multiSearch ist total falsch. Schau dir nochmal mein Bsp von unten an. Hier, dieser Teil fundamentale Teil fehlt bei dir:

Java:
      /* Warte, bis alle Threads ihre Berechnungen durchgeführt haben */
        for (Summe sum : threadArray) {
            synchronized (sum) {
                while (!sum.isFertig()) {
                    try {
                        sum.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }

Und in deiner run-Methode ein notify() einbauen, siehe auch mein Code.

Übrigens: diese singleSearch() sollte auch einen neuen LinearThread starten.

Das mit dem Interval hast du ja richtig gemacht, fast 1:1 wie in meinem Bsp, wo ich das auch mache. Aber vergleich mal den Rest von dem Code den ich gepostet hab mit deinem. wie gesagt es geht um's wait/notify, und achte darauf dass dein "done" auf jeden fall volatile ist:

Java:
private volatile boolean done;

Ohne volatile kann's sein, dass der main-Thread gar nciht mitkriegt, wenn das auf true gesetzt wird, und ewig wartet.

edit: Quatsch, sorry.. muss nicht volatile sein, wenn du's so machst wie ich, weil du ja ein syncrhonized drumrum hast.
 
Zuletzt bearbeitet:

Sophie

Bekanntes Mitglied
Oh.. Du, wie soll ich sagen.. Das ist.. total falsch. :D

Nein!!!
Diese Threads lassen einen ja wirklich verzweifeln.

Also ich habe mich jetzt mal sehr genau an Deinen Code gehalten und hoffe das, dass nun so in Ordnung ist. Was meinst Du?

Java:
public void run() {

			for (int i = start; i <= end; i++) {
				if (arr[i] == searchKey) {
					done = true;
				}
				start++;
			}

		synchronized (this) {
			notifyAll();
		}
	}

Java:
public static int searchMulti(int array[], int key, int numThreads) {

		int intervall = array.length / numThreads;
		int rest = array.length % numThreads;

		int start = 0;
		int end = 0;

		//Thread[] ts = new Thread[numThreads];
		LineareSuche[] threadArray = new LineareSuche[numThreads];

		// Creates Threads
		for (int j = 0; j < numThreads; j++) {

			if (j == 0) {
				start = 0;
				end = intervall + rest - 1;
			} else {
				start = end + 1;
				end = end + intervall;
			}
			LineareSuche ls = new LineareSuche(array, start, end, key);
			threadArray[j] = ls;
			//ts[j] = new Thread(new LineareSuche(array, start, end, key));
		}

		// Starts the Threads
		for (LineareSuche ls : threadArray) {
			new Thread(ls).start();
		}

		// Warte, bis alle Threads fertig sind
		for (LineareSuche ls : threadArray) {
			synchronized (ls) {
				while (done != true) {
					try {
						ls.wait();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}
		return index;
}
 

hdi

Top Contributor
Jetzt ist die searchMulti wieder viel langsamer als die searchSingle
Und damit meinst du wohl dass searchMutli unendlich lange dauert, kann das sein?! ;)

Drei Fehler hast du noch drin, 2 davon führen dazu dass searchMulti (evtl) niemals stoppt:

Java:
for (LineareSuche ls : threadArray) {
            synchronized (ls) {
                while (done != true) { // -------------------------------- done => ls.done !!
                    try {
                        ls.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
}

Ist klar, oder? Du willst prüfen ob jeder einzelne Thread fertig ist, also ls.done, nicht this.done. Oder hast du done jetzt auch static gemacht? Das gehört non-static!!

Der andere Fehler liegt in der run-Methode: Für den Fall, dass die zu suchende Zahl im Array (bzw dem Teil-Intervall, der einem Thread zugewiesen wird), gar nicht vorhanden ist, wird done nicht auf true gesetzt. D.h. er beendet die run-Methode, ruft notify() auf, was dazu führt dass der main-Thread aufgeweckt wird, aber in seinem nächsten while ls.done() ist done noch immer false -> der main thread blockiert wird -> Deadlock. Also richtig:

Java:
public void run() {
 
            for (int i = start; i <= end; i++) {
                if (arr[i] == searchKey) {
                    break;
                }
                start++;
            }

        synchronized (this) {
            done = true;
            notifyAll();
        }
    }

So, und der letzte Fehler ist dass du bei searchMulti in der run-Methode irgendwie den (static int) index gar nicht zuweist, wenn du den Wert findest?! Außerdem kann's damit auch Probleme geben da Zugriff darauf nicht synchronisiert ist. Also:

Java:
// in der run-Methode:
synchronized(LineareSuche.class){
   index = i;
}

// in der searchMultiMethode / searchSingleMethode:
synchronnized(LineareSuche.class){
   return index;
}

Wobei das nicht so toll gelöst ist mit dem Index, dass der static ist. Du müsstest zB bei deinen Test den immer wieder auf 0 zurücksetzen um zu prüfen dass die Threads auchw irklich den richtigen Index gefunden haben und nicht einfach der alte Wert genommen hat, den zB searchSingle() davor berechnet hat. Ich würd jedem Thread noch ne Instanz-Variablen foundIndex oder so geben, die -1 ist wenn er nix findet und wenn du's findest speicherst du es ab. Der main-Thread ruft dann getFoundIndex() auf wenn done == true ist. Wenn deine Testdaten passen sollte ja nur ein Thread die Zahl gefunden haben, und das returned du dann. Dann brauchst du kein static int index mehr und kannst die die o.g. Synchronisation auch sparen.

Ich glaub die fehlen noch so ein bisschen die Basics bei Multi-threading zwecks synchronisation. Du scheinst nicht zu verstehen was synchronized und wait/notify tut oder?
 
Zuletzt bearbeitet:

Marco13

Top Contributor
Oh.. Du, wie soll ich sagen.. Das ist.. total falsch. :D

Man nicht so demotivierend... "total falsch" war das nicht. Das Warten auf das Threadende war in der ursprünglichen Version schon drin, mit thread.join(), aber das war eben noch mit dem System.exit kombiniert und deswegen nicht praktikabel. Ansonsten ist das ganze konzeptuell ja schon richtig - was noch fehlt, ist
- Das Warten auf das Ende
- Und damit implizit: Dass man mitkriegen muss wenn einer der Threads die Zahl gefunden hat.

Letzteres ist eben das "schwierige" in diesem Fall. Man will ja auch eigentlich nicht warten, bis ALLE Threads fertig sind. Stell' dir vor, der erste Thread findet das gesuchte Element sofort, und alle anderen Threads suchen noch 100ms weiter, obwohl schon klar ist, dass sie nichts finden werden.

Nochmal ein Ansatz:
Java:
public class LineareSucheTest {

    public static void main(String[] args) {

        // Array Size and Search Key will be given as an argument
        int arraySize = 100000000;
        int searchKey = 99999999;// Integer.parseInt(args[1]);

        // fills Array arr with Integers
        int[] arr = new int[arraySize];
        for (int j = 0; j < arr.length; j++) {
            arr[j] = j;
        }

        testSearchMulti(arr, searchKey, 4);
        testSearchSingle(arr, searchKey);
    }

    private static void testSearchSingle(int array[], int key) {
        long start = System.currentTimeMillis();
        for (int i = 0; i <= 0; i++) {
        int index = new LineareSuche().searchSingle(array, 0, array.length, key);
        }
        long stop = System.currentTimeMillis();
        double zeit = (stop - start);
        System.out.println("searchSingle took " + zeit + " ms");
    }

    private static void testSearchMulti(int array[], int key, int numThreads) {
        long start = System.currentTimeMillis();
        for (int i = 0; i <= 0; i++) {
        int index = new LineareSuche().searchMulti(array, key, numThreads);
        }
        long stop = System.currentTimeMillis();
        double zeit = (stop - start);
        System.out.println("searchMulti took " + zeit + " ms");
    }

}




class LineareSuche {

    /**
     * Returns the index of the key inside the array, searching between the
     * given min/max indices, or -1 if the key is not found
     */
    public int searchSingle(int array[], int min, int max, int key) {
        for (int i = min; i < max; i++) {
            if (array[i] == key) {
                done = true;
                result = i;
                return i;
            }
            if (done)
            {
                return -1;
            }
        }
        return -1;
    }

    private volatile boolean done = false;
    private volatile int result = -1;

    public int searchMulti(final int array[], final int key, int numThreads) {
        done = false;

        int intervall = (int)Math.ceil(array.length / numThreads);

        // Creates Threads
        Thread[] ts = new Thread[numThreads];
        for (int j = 0; j < numThreads; j++) {

            final int min = j * intervall;
            final int max = Math.min(min + intervall, array.length);

            ts[j] = new Thread(new Runnable()
            {
                @Override
                public void run()
                {
                    searchSingle(array, min, max, key);
                }
            });
        }

        // Starts the Threads
        for (int k = 0; k < numThreads; k++) {
            ts[k].start();
        }

        for (int k = 0; k < numThreads; k++) {
            try {
                ts[k].join();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return result;
    }
}


@Sophie: Beachte auch, dass es bei den Zeitmessungen GANZ entscheidend darauf ankommt, nach WELCHEM Wert man sucht. Wenn man nach '1' sucht, findet die Single-Threaded version das gesuchte Element sofort, und ist sicher schneller als die multi-THreaded version. Wenn man einen Array mit 1000 Elementen für die Multithreaded version in 4 Teile aufteilt, dann wird z.B. das Element 751 vom 4. Thread sofort gefunden, und das wäre sehr schnell, das Element 999 würde aber erst etwas später gefunden, und es wäre etwas langsamer (aber theoretisch(!!!)) trotzdem noch 4x so schnell wie bei der single-Threaded Suche.
 

hdi

Top Contributor
Man nicht so demotivierend... "total falsch" war das nicht.
Die Arbeitsverteilung war korrekt, das hatte ich auch gesagt. Aber im Hinblick auf das Thema Threading... Ja, sie hat die Klasse Thread genutzt, und die start()-Methode gefunden. Aber ansonsten gibt's da im Hinblick auf das, was das Programm (multi-threaded) tun soll, nun mal nicht mehr allzu viel an korrektem Ansatz. Ich habe mehrere Probleme mit ihrem Code gelistet. Aber es geht mir natürlich nicht drum zu demotivieren, sonst hätte ich geschrieben "Lass es einfach sein". Aber der/die TO zeigt ja genug Interesse daran das richtig hinzukriegen, ich denk das war jetzt nicht so traumatisierend :D

Das Warten auf das Threadende war in der ursprünglichen Version schon drin
Okay, ich hab mich erst ein wenig später in die Diskussion eingehakt, und mein Beitrag bezog sich auf das was sie jetzt am Ende gemacht hat.

Man will ja auch eigentlich nicht warten, bis ALLE Threads fertig sind. Stell' dir vor, der erste Thread findet das gesuchte Element sofort, und alle anderen Threads suchen noch 100ms weiter, obwohl schon klar ist, dass sie nichts finden werden.
Stimmt, daran hatte ich bisher auch noch nicht gedacht. Trotzdem würde ich vorschlagen, das Step by Step zu machen. Es würde ja vorerst reichen das unter den Tisch fallen zu lassen, würd auch schon Performance-Gewinn bringen.* Und wenn sie es soweit geschafft hat dass der Aufruf wirklich mit den Threads synchronisiert ist, dann kann man sich darum kümmern. Sonst kommt noch weitere Komplexität hinzu, das macht das synchronisieren nicht unbedingt einfacher.

*Sofern die gesuchte Zahl nicht im ersten Teilintervall vorhanden ist. Dass der gesuchte Wert da eine Rolle spielt das hast du ja erläutert
 

Marco13

Top Contributor
Trotzdem würde ich vorschlagen, das Step by Step zu machen. Es würde ja vorerst reichen das unter den Tisch fallen zu lassen, ... wenn sie es soweit geschafft hat dass der Aufruf wirklich mit den Threads synchronisiert ist, dann kann man sich darum kümmern.

Ja, das zieht sich ein bißchen wie ein roter Thread durch diesen Faden (pun intended :D ) und auch durch viele andere: Ist es hilfreicher, den zuerst geposteten Ansatz des TO (des, nicht der - davon gehe ich zumindest aus ;)) über den Haufen zu werfen, und einen komplett anderen ("richtigeren") Ansatz zu posten, oder zu versuchen, den TO mit "minimalen Änderungen am Originalprogramm" in die richtige Richtung zu schubsen? Schwierig, hängt wohl vom Einzelfall ab...
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
S Multi-Threaded Binäre Suche Java Basics - Anfänger-Themen 29
BadBat Multi Threading Java Basics - Anfänger-Themen 2
J ConcurrentCalculation Multi Threads in Java Java Basics - Anfänger-Themen 3
S Methoden Multi-Thread und Methoden Objects. Java Basics - Anfänger-Themen 1
X Multi Array zu einzelnen Arrays trennen Java Basics - Anfänger-Themen 7
C Threads Threaded Bilder bearbeiten Java Basics - Anfänger-Themen 8
K threaded server Java Basics - Anfänger-Themen 18
P Neue Java v8 JRE Version nicht über alte drüber installierbar: Wie sonst? Java Basics - Anfänger-Themen 7
A Eclipse IDE - Wie bekomme ich eine ältere Version Java Basics - Anfänger-Themen 6
Zrebna Umgebungsvariable Wieso wird meine verwendete JDK-Version in der Prompt nicht erkannt? Java Basics - Anfänger-Themen 6
M Java Version Verständnisfrage Java Basics - Anfänger-Themen 16
J Welche Java-Version installieren Java Basics - Anfänger-Themen 9
pkm Eclipse wie mit anderer JAVA-Version starten? Java Basics - Anfänger-Themen 1
U duplicate entry: Version.java.template Java Basics - Anfänger-Themen 0
N Javac -version der Befehl ist entweder falsch geschrieben oder...... Java Basics - Anfänger-Themen 8
J class version 52 und 56 Java Basics - Anfänger-Themen 6
U UnsupportedClassVersionError trotz neuster JRE und JDK Version Java Basics - Anfänger-Themen 7
dapzoo Class File Version zu niedrig? Ausführen über Eingabeaufforderung nicht möglich Java Basics - Anfänger-Themen 14
I Richtige Java-Version finden? Java Basics - Anfänger-Themen 17
J Windows Version herrausfinden Java Basics - Anfänger-Themen 3
P Javaprogramm mit einer bestimten Version starten Java Basics - Anfänger-Themen 5
A Erste Schritte Programm in Shell mit bestimmter Java-Version aufrufen Java Basics - Anfänger-Themen 10
B Netbeans Java Version 8.0.2 und Yosemite Java Basics - Anfänger-Themen 1
G Welche Java-Version auf meinem Rechner? Java Basics - Anfänger-Themen 2
H JDK installieren Ältere Version besorgen Java Basics - Anfänger-Themen 2
H java version updaten Java Basics - Anfänger-Themen 11
K Welche Java Version ist die richtige Java Basics - Anfänger-Themen 3
M System.getProperty("java.vm.version") liefert build-Version Java Basics - Anfänger-Themen 4
M Java 64 bit version funktoniert nicht bei win 64 bit Java Basics - Anfänger-Themen 6
J Kompilieren in anderern Java-Version? Java Basics - Anfänger-Themen 15
T Compiler-Fehler Version nicht aktuell? Java Basics - Anfänger-Themen 8
L Problem, Backslash einzugeben - Version? Java Basics - Anfänger-Themen 11
D Letztes Änderungs-Datum als Version automatisch eintragen Java Basics - Anfänger-Themen 5
M JDK installieren Compiler Version Java Basics - Anfänger-Themen 4
K kan 64Bit Version unter Win7Pro64 nicht installieren Java Basics - Anfänger-Themen 12
Kukulkan Java-Version (ME, SE) erkennen und darauf reagieren? Java Basics - Anfänger-Themen 35
S Falsche Version? Java Basics - Anfänger-Themen 2
K JDK-Version einer kompilierten Java-Klasse? Java Basics - Anfänger-Themen 6
agent47 Java Version vergleichen Java Basics - Anfänger-Themen 6
G Java Version steuern Java Basics - Anfänger-Themen 12
nrg Serial Version ID? Java Basics - Anfänger-Themen 16
R Java Version herausfinden..? Java Basics - Anfänger-Themen 1
X Java Eclipse Version: 3.4.1 meldet manchmal keine Fehler Java Basics - Anfänger-Themen 17
K Problem beim installieren des JDK 1.6+ version Java Basics - Anfänger-Themen 3
G java version umstellen von 1.4 auf 1.6 unter linux Java Basics - Anfänger-Themen 4
A brauche eine Lösung für Problem bei Moorhuhn-Version Java Basics - Anfänger-Themen 5
J Wie in Windows Installation und Version von Java ermitteln? Java Basics - Anfänger-Themen 2
G Welche Version zuerst? Java Basics - Anfänger-Themen 11
mwildam Welche Java-Version (SE oder EE)? Java Basics - Anfänger-Themen 9
D Java-Version anzeigen lassen Java Basics - Anfänger-Themen 4
G Version von Anwendung mit Eclipse oder anders festlegen Java Basics - Anfänger-Themen 8
G Mailversand mit Java in der Version 1.3? Java Basics - Anfänger-Themen 2
H java.lang.UnsupportedClassVersionError: Bad version number Java Basics - Anfänger-Themen 2
C JVM-Version ermitteln Java Basics - Anfänger-Themen 4
G falsche Version Java Basics - Anfänger-Themen 3
M java version auslesen Java Basics - Anfänger-Themen 3
ff eclipse ::--> serial version uid Java Basics - Anfänger-Themen 8
K Anwendung mit anderer Java-Version Starten Java Basics - Anfänger-Themen 9
M Datei bei Class und Jar Version ladbar? Java Basics - Anfänger-Themen 2
G Version auslesen Java Basics - Anfänger-Themen 6
U Riesen Problem - unsupported major.minor version 49.0 Java Basics - Anfänger-Themen 5
H Java Version 5.0 Java Basics - Anfänger-Themen 6
F java version prüfen Java Basics - Anfänger-Themen 9
S JDK-Version auslesen Java Basics - Anfänger-Themen 3
B Frage zur Applet-Version von CoolStrip Java Basics - Anfänger-Themen 9

Ähnliche Java Themen

Neue Themen


Oben