/ / Thread.start () ruft die Thread.run () - Methode nicht auf - Java

Thread.start () ruft die Thread.run () - Methode nicht auf - Java

In meinen Projekten gibt es 3 Klassen, die sich erstreckenThread, jeder von ihnen berechnet eine ganze Zahl. Ich muss sie ausführen, um alle drei berechneten Werte zu erhalten. Dieser Prozess muss für alle ganzen Zahlen in einem bestimmten Bereich durchgeführt werden.

Dies ist einer meiner Threads:

public class FactorialNumber extends Thread {
private int number;

public void setNumber(int number) {
this.number = number;
}

public void run() {
try {
sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.print(NumbersOperations.getFactorial(number));
}
}

Dies ist eine Methode, die versucht, Threads zu starten:

public static void getThreevalues() throws InterruptedException {
int startOfRange = getBorder("Enter the left border of range: ");
int endOfRange = getBorder("Enter the right border of range: ");
for(int i = startOfRange; i <= endOfRange; i++) {
PrimeNumber primeNumber = new PrimeNumber();
FibonachiNumber fibonachiNumber = new FibonachiNumber();
FactorialNumber factorialNumber = new FactorialNumber();
primeNumber.setNumber(i);
fibonachiNumber.setNumber(i);
factorialNumber.setNumber(i);
System.out.print("Number: " + i);
System.out.print(" is prime number ");
primeNumber.start();
System.out.print(". Fibonachi - " );
fibonachiNumber.start();
System.out.print(". Factorial - ");
factorialNumber.start();
System.out.println();

}
}

Nachdem ich meinen Code ausgeführt habe, erhalte ich Folgendes:

Number: 3 is prime number . Fibonachi - . Factorial -
Number: 4 is prime number . Fibonachi - . Factorial -
Number: 5 is prime number . Fibonachi - . Factorial -
Number: 6 is prime number . Fibonachi - . Factorial -
true2hi6falsetrue5hi2483falsehi720hi120

Soweit ich weiß, ruft start () die Methode run () nicht auf. In meiner Run - Methode gibt es "sleep" (500), aber das Ergebnis wird nur in der Konsole ohne Ruhezustand angezeigt.

Ich würde mich über jede Hilfe freuen, da ich bereits zu viel Zeit damit verbracht habe und das Problem leider nicht gelöst habe.

Antworten:

5 für die Antwort № 1

Es gibt ein paar Dinge, die Sie verwirren werden. Beginnen wir mit etwas, das nicht offensichtlich ist:

System.out.print() stellt durch Sperren sicher, dass die Threads nicht übereinander gedruckt werden. Wenn Sie also zwei Threads und einen haben, wird gedruckt foo und die anderen Drucke barSie können entweder bekommen foobar oder barfoo aber nie fboaro (= kein Mischen).

Das bedeutet auch, wenn ein Thread (der Haupt- oder einer Ihrer drei Berechnungsthreads) etwas druckt, warten alle anderen Threads, die gleichzeitig drucken möchten.

Weiter: Beim Starten von Threads werden diese nicht in die Warteschlange gestellt. Wenn Sie N Threads starten, führt das System deren gesamten Code gleichzeitig aus. Wenn alle 500ms schlafen, wird dieser Schlaf parallel sein. Wenn Sie möchten, dass Threads in einer bestimmten Reihenfolge ausgeführt werden, müssen Sie Warteschlangen und Sperren verwenden.

Zuletzt: Sie starten die Threads, aber Sie warten nie auf die Ergebnisse. Was also passiert, ist, dass der Hauptthread die Threads startet und dann fortfährt (wahrscheinlich endet). Dann warten alle drei Threads gleichzeitig auf 500 ms und versuchen dann alle, das Ergebnis zu berechnen und gleichzeitig auszudrucken.

Wie Sie wahrscheinlich zu verstehen beginnen, ist das alles ziemlich komplex und nervig. Aus diesem Grund hat Java 6 das Concurrent Framework eingeführt, das viele dieser Probleme löst.

Kurz gesagt, erstellen Sie keine Threads mehr. Erstellen Callables die das gewünschte Ergebnis zurückgeben und dann an senden ExecutorService. Der Dienst wird sie ausführen und zurückkehren Futures. Sie können dann die Zukunft nach einem Ergebnis abfragen.

Auf diese Weise müssen Sie sich nicht mit Threading-Problemen auf niedriger Ebene, Synchronisierung, Sperren und Warteschlangen befassen.

Verbunden:

(Bearbeiten, um das Entfernen von Downvote zuzulassen.)


0 für die Antwort № 2

Ihre Ergebnisse sind wahrscheinlich in der letzten Zeichenfolge versteckt: "true2hi6falsetrue5hi2483falsehi720hi120". Alle Threads führen tatsächlich den Befehl aus:

System.out.print(NumbersOperations.getFactorial(number));

Wenn die Schleife beendet ist, müssen sie 0,5 Sekunden warten. Sie haben auch eine print Methode, um dies zu tun, nicht ein printlnDaher wird jedes Ergebnis an ein anderes "geklebt". Wie aus den Kommentaren hervorgeht, werden Threads nicht einzeln ausgeführt, sie warten nämlich nicht auf das Ende des vorherigen Thread.


0 für die Antwort № 3

Und eine weitere Sache, die Sie tun müssen: Warten Sie, bis die Fäden fertig sind. Ich würde drei Anrufe von erwarten Thread.join() andernfalls könnte Ihr Programm die Threads beenden und abbrechen (Sie haben sie als Daemon markiert, oder?), bevor sie das Ergebnis drucken können.


0 für die Antwort № 4

Danke an alle! Es hat mir geholfen, Fäden besser zu verstehen. Um das Problem zu lösen, habe ich die Methode join () verwendet. Die Methode, mit der Threads gestartet werden, sieht also folgendermaßen aus:

public static void getThreevalues() throws InterruptedException {
int startOfRange = getBorder("Enter the left border of range: ");
int endOfRange = getBorder("Enter the right border of range: ");
for(int i = startOfRange; i <= endOfRange; i++) {
PrimeNumber primeNumber = new PrimeNumber();
FibonachiNumber fibonachiNumber = new FibonachiNumber();
FactorialNumber factorialNumber = new FactorialNumber();
primeNumber.setNumber(i);
fibonachiNumber.setNumber(i);
factorialNumber.setNumber(i);
System.out.print("Number: " + i);
primeNumber.start();
primeNumber.join();
fibonachiNumber.start();
fibonachiNumber.join();
factorialNumber.start();
factorialNumber.join();
Thread.sleep(2000); // this line"s useful to present result by lines
System.out.println();
}
}

und meine fadenklassen habe ich nicht geändert.