/ / Warum zeigt meine Eingabe einen Thread, der nach einem anderen Thread ausgeführt wird, nicht gleichzeitig? - Java, Multithreading

Warum zeigt meine Eingabe einen Thread, der nach einem anderen Thread ausgeführt wird, nicht gleichzeitig? - Java, Multithreading

Ich habe das Konzept eines Threads recherchiert und festgestellt, dass Code in zwei Prozessen gleichzeitig ausgeführt werden soll. Hier ist mein Code

public class Connor extends Thread{

public void run() {
for(int i=0; i< 10; i ++){
System.out.println("Hello " + i);
}

public static void main(String[] args){
Connor runner1 = new Connor();
Connor runner2 = new Connor();
runner1.start();
runner2.start();
}
}

Und meine Ausgabe http://imgur.com/yAZqgal

Es scheint, als ob die beiden Themen bei beginnenzur gleichen Zeit (getrennte Prozesse, wie durch die beiden führenden Nullen angegeben), aber einer wird ausgeführt (1-9) und dann der andere wird ausgeführt (1-9). Wenn sie nicht annehmen, dass auch die Threads (1,1,2,2, ...) miteinander verwoben werden, werden sie beide auf der Konsole gedruckt. Ich habe nachgeforscht und festgestellt, dass start die richtige Methode ist, da die Thread-Klasse angewiesen wird, die run-Methode in einem anderen Thread auszuführen. Kann jemand erklären, warum ich diese Ausgabe erhalte?

Antworten:

5 für die Antwort № 1

Angenommen, Sie haben zehn Besorgungen, die Sie erledigen müssen, und IhreSchwester hat zehn Besorgungen, die sie machen muss, und Sie haben nur ein Auto. Bringst du das Auto nach jeder Besorgung zurück und wechselst den Fahrer? Natürlich nicht. Das wäre absurd ineffizient. Jeder Thread benötigt im Grunde nur den Ausgabestream. Es wäre also absurd, sie eng zu verschachteln.


3 für die Antwort № 2

Ihr Code sieht gut aus. Ich vermute mal, dass deine Threads nicht parallel laufen, nur weil sie zu schnell enden. Ändern Sie das Schleifenlimit von 10 auf 1000 und Sie werden den Effekt sehen.

Der Startfaden selbst ist relativ schwerOperation. Ihr Code startet den ersten Thread und dann den zweiten. Der erste Thread, der einmal gestartet wurde, wird beendet, bevor der zweite Thread die Möglichkeit hat, seine Geschäftslogik auszuführen.


2 für die Antwort № 3

Bei Multithreading gibt es keine GarantieWelcher Thread zu welchem ​​Zeitpunkt vom Prozessor ausgeführt wird, ist unvorhersehbar. In diesem Fall wird für jeden Durchlauf eine andere Ausgabe generiert.

Wenn Sie den gewünschten Ausgang suchen, benötigen Sie einen Synchronisationsblock. mit wait und notify Sie können es leicht erreichen.

Bitte schauen Sie sich unten die Lektion direkt an Offizielle Oracle-Website:

Hinweis: wait & notify muss in der aufgerufen werden synchronized blockieren und kann auf dasselbe Objekt zugreifen, auf dem es synchronisiert ist.

Beispielcode: (Inline-Kommentare lesen)

public class Connor extends Thread {

private static Connor runner1 = new Connor();
private static Connor runner2 = new Connor();

public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("Hello " + i);

// wake up another thread to come out from wait state
if (runner1 == this) {
// wake up runner2
synchronized (runner2) {
runner2.notify();
}
} else {
// wake up runner1
synchronized (runner1) {
runner1.notify();
}
}

synchronized (this) {
try {
// say current thread to wait until notify by another thread
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

public static void main(String[] args) {
runner1.start();
runner2.start();
}
}

Ausgabe:

Hello 0
Hello 0
Hello 1
Hello 1
Hello 2
Hello 2
Hello 3
Hello 3
Hello 4
Hello 4
Hello 5
Hello 5
Hello 6
Hello 6
Hello 7
Hello 7
Hello 8
Hello 8
Hello 9
Hello 9

0 für die Antwort № 4

Warum zeigt meine Eingabe einen Thread, der nach einem anderen Thread ausgeführt wird, nicht gleichzeitig?

Die allgemeine Erklärung ist, dass die Thread-Planung nicht vorhersehbar ist. Verschachtelung kann passieren ... oder es nicht dürfen. Dies ist für Java-Threading von grundlegender Bedeutung. (Und in der Tat zum Threading in den meisten anderen Sprachen.)

Wenn Sie eine Thread-Ausführung zum Interleaven in ein benötigenEs ist völlig vorhersehbar, dass Sie eine Art Hand-Shake-Mechanismus implementieren müssen, bei dem ein Thread darauf wartet, dass ein anderer etwas unternimmt und weitermacht. Dies ist jedoch kompliziert und macht den Zweck der Verwendung von Threading in der Regel zunichte.

FWIW: Die Antwort von @Braj zeigt, wie Sie ein striktes Interleaving implementieren können. Beachten Sie jedoch, dass dies effektiv bedeutet, dass jeweils nur ein Thread ausgeführt wird. Außerdem führt das Warten / Benachrichtigen zu viel Arbeit für den Thread Scheduler ... einige, dass die Anwendung deutlich langsamer ausgeführt wird, als wenn Sie nur die Arbeit an einem Thread getan hätten.


In diesem speziellen Beispiel gibt es zwei Probleme, die zusammen eine kurzfristige Verschachtelung unwahrscheinlich machen:

  1. Erstellen eines neuen nativen Threads in Java istrelativ teuer, da es normalerweise erforderlich ist, einen Speicherblock vom Betriebssystem anzufordern, um den Thread-Stapel unterzubringen. Dies wiederum hat zur Folge, dass das Betriebssystem mit Seitentabellen "herumspielt", einen Speicherblock auf Null setzt und so weiter.

  2. Die native Thread-Planung wird von der implementiertBetriebssystem, und es arbeitet auf einer ziemlich groben Ebene ... weil dies die effizienteste Art ist, aus der Perspektive einer typischen Anwendung zu arbeiten. (Das Wechseln von Thread- "Kontexten" in einem Computer der PC-Klasse ist ein relativ teurer Vorgang, und der Thread-Scheduler selbst muss möglicherweise noch etwas erledigen.)

In Ihrem Beispiel kann der erste Thread zehnmal "Hallo" sagen, bevor der zweite Thread für die Planung bereit ist.