Java-Thread-Priorität hat keine Auswirkung

8

Dies ist ein Test zur Thread-Priorität. Der Code stammt von Thinking in Java S.809

%Vor%

Ich frage mich, warum ich kein reguläres Ergebnis wie:

bekomme %Vor%

aber ein zufälliges Ergebnis (jedes Mal wenn ich es ausführe):

%Vor%

Ich benutze i3-2350M 2C4T CPU mit Win 7 64 bit JDK 7. Ist das wichtig?

    
Cory Lee 20.08.2012, 13:27
quelle

10 Antworten

12
  

Java-Thread-Priorität hat keine Auswirkung

Thread-Prioritäten funktionieren auf den meisten Betriebssystemen, haben aber oft nur minimale Auswirkungen. Prioritäten helfen, die Threads zu ordnen, die sich nur in der Ausführungswarteschlange befinden, und ändern nicht die Häufigkeit, mit der die Threads in einer größeren Warteschlange ausgeführt werden, es sei denn, Sie führen in jedem Thread eine Menge CPU aus.

Ihr Programm sieht so aus, als würde es eine Menge CPU verwenden, aber wenn Sie weniger Kerne als Threads haben, sehen Sie möglicherweise keine Änderung in der Ausgabe-Reihenfolge, indem Sie Ihre Thread-Prioritäten setzen. Wenn eine freie CPU vorhanden ist, wird sogar ein Thread mit niedrigerer Priorität ausgeführt.

Außerdem werden Threads niemals ausgehungert. Selbst ein Thread mit geringerer Priorität wird in einer solchen Situation oft genug ausgeführt. Sie sollten sehen, dass Threads mit höherer Priorität eine bestimmte Zeit haben, in der sie häufiger ausgeführt werden , aber es bedeutet nicht, dass Threads mit niedrigerer Priorität darauf warten, dass sie beendet werden, bevor sie ausgeführt werden.

Auch wenn Prioritäten dazu beitragen, einen Thread mehr CPU als die anderen zu geben, unterliegen Thread-Programme den Race-Bedingungen help injizieren eine große Menge an Zufälligkeit zu ihrer Ausführung. Was Sie jedoch sehen sollten, ist, dass der Thread mit der maximalen Priorität die Nachricht 0 häufiger ausgibt als der Rest. Wenn Sie der println() die Priorität hinzufügen, sollte dies bei einer Anzahl von Läufen offensichtlich werden.

Es ist auch wichtig zu beachten, dass System.out.println(...) ist synchronized Methode, die IO schreibt, die dramatisch beeinflussen wird, wie die Threads interagieren und die verschiedenen Threads sich gegenseitig blockieren. Darüber hinaus kann Thread.yield(); ein No-Op sein, abhängig davon, wie das Betriebssystem seine Thread-Planung durchführt.

  

aber ein zufälliges Ergebnis (jedes Mal wenn ich es ausführe):

Richtig. Die Ausgabe von einem Thread-Programm ist selten, wenn überhaupt "perfekt", da die Threads asynchron ausgeführt werden. Wir wollen, dass die Ausgabe zufällig ist, weil wir wollen, dass die Threads unabhängig voneinander parallel laufen. Das ist ihre Macht. Wenn Sie eine präzise Ausgabe erwarten, sollten Sie keine Threads verwenden.

    
Gray 20.08.2012, 13:34
quelle
12

Die Threadpriorität ist implementierungsabhängig. Insbesondere in Windows:

  

Die Thread-Priorität ist nicht sehr aussagekräftig, wenn alle Threads miteinander konkurrieren   für die CPU. ( Quelle )

Das Buch "Java Concurrency in Practice" sagt auch zu

  

Vermeiden Sie die Versuchung, Thread-Prioritäten zu verwenden, da sie zunehmen   Plattformabhängigkeit und kann zu Lebhaftigkeitsproblemen führen. Am meisten gleichzeitig   Anwendungen können die Standardpriorität für alle Threads verwenden.

    
Andrea Bergia 20.08.2012 13:34
quelle
9

Die Thread-Priorität garantiert nicht die Ausführungsreihenfolge. Es kommt ins Spiel, wenn die Ressourcen begrenzt sind. Wenn das System aufgrund von Speicher oder CPU Einschränkungen unterliegt, werden die Threads mit der höheren Priorität zuerst ausgeführt. Angenommen, Sie haben genügend Systemressourcen (was ich für ein einfaches Programm und die von Ihnen geposteten Systemressourcen annehmen würde), dann haben Sie keine Systemeinschränkungen. Hier ist ein Blog-Post (nicht mein Post) Ich fand, dass bietet mehr Informationen darüber: Warum Thread Priorität selten wichtig ist .

    
Philip Tenn 20.08.2012 13:38
quelle
6

Lass es uns einfach halten und direkt zur Quelle gehen ...

  

Jeder Thread hat eine Priorität. Wenn es Wettbewerb für die Verarbeitung gibt   Ressourcen werden Threads mit höherer Priorität in der Regel ausgeführt   Präferenz für Threads mit niedrigerer Priorität. Eine solche Präferenz ist nicht,   jedoch eine Garantie, dass der Thread mit der höchsten Priorität immer sein wird   running und Thread-Prioritäten können nicht zuverlässig verwendet werden   gegenseitiger Ausschluss.

  • aus der Java-Sprachspezifikation (2. Ausgabe) S.445.

Auch ...

  

Obwohl Thread-Prioritäten in Java und vielen Referenzen existieren   dass die JVM immer einen der Threads mit der höchsten Priorität auswählt   für die Terminplanung [52, 56, 89] ist dies zur Zeit nicht gewährleistet   Java-Sprache oder virtuelle Maschinenspezifikationen [53, 90]. Prioritäten   sind nur Hinweise für den Scheduler [127, Seite 227].

  • aus Testing Concurrent Java Components (Dissertation, 2005) p. 62.

  • Referenz 127, Seite 227 (aus dem obigen Auszug) stammt von Komponentensoftware: Über objektorientierte Programmierung (von C. Szyperski), Addison Wesley, 1998.

Kurz gesagt: verlässt sich nicht auf Thread-Prioritäten .

    
xagyg 19.08.2013 10:42
quelle
4

Die Threadpriorität ist nur ein Hinweis auf den OS Taskplaner. Der Task-Scheduler wird nur versuchen , einem Thread mit höherer Priorität mehr Ressourcen zuzuweisen, jedoch gibt es keine expliziten Garantien.

Tatsächlich ist es nicht nur relevant für Java oder JVM. Die meisten Nicht-Echtzeit-Betriebssysteme verwenden Thread-Prioritäten (verwaltet oder nicht verwaltet) nur auf suggestive Weise.

Jeff Atwood hat einen guten Beitrag zum Thema: " Thread-Prioritäten sind böse "

  

Hier ist das Problem. Wenn jemand die Arbeit beginnt, die "Kond" machen wird   true auf einem Thread mit niedrigerer Priorität (der Produzent) und dann der Zeitpunkt von   Das Programm ist so ausgelegt, dass der Thread mit der höheren Priorität dies ausgibt   Spinnerei (der Verbraucher) wird eingeplant, der Verbraucher verhungern wird   Produzent komplett. Dies ist ein klassisches Rennen. Und obwohl es da ist   ein expliziter Sleep drin, der es dem Producer nicht erlaubt   geplant sein, weil es eine niedrigere Priorität hat. Der Verbraucher wird nur   Drehen Sie sich für immer und wenn sich keine freie CPU öffnet, wird der Produzent niemals   produzieren. Ups!

    
oleksii 20.08.2012 13:34
quelle
3

Wie in anderen Antworten erwähnt, ist Thread-Priorität eher ein Hinweis als eine Definition einer strikten Regel.

Das heißt, selbst wenn die Priorität strikt (er) berücksichtigt würde, würde Ihr Test-Setup nicht zu dem Ergebnis führen, das Sie als "erwartet" bezeichnen. Sie erstellen zuerst 5 Threads mit gleicher Priorität und einen Thread mit hoher Priorität.

  • Die von Ihnen verwendete CPU (i3) hat 4 native Threads. Selbst wenn High Priory implizieren würde, dass der Thread ohne Unterbrechung läuft (was nicht wahr ist), erhalten die Threads mit niedriger Priorität 3/4 der CPU-Leistung (vorausgesetzt, dass keine andere Task ausgeführt wird). Diese CPU-Leistung ist 5 Threads zugeordnet, daher laufen die Threads mit niedriger Priorität mit 4 * 3/4 ​​* 1/5 = 3/5 der Geschwindigkeit des Thread mit hoher Priorität. Nachdem der Thread mit hoher Priorität abgeschlossen ist, werden die Threads mit niedriger Priorität mit 4/5 der Geschwindigkeit des Threads mit hoher Priorität ausgeführt.

  • Sie starten die Threads mit niedriger Priorität vor den Threads mit hoher Priorität. Daher beginnen sie etwas früher. Ich erwarte, dass in den meisten Systemen "Priorität" nicht bis in die Nanosekunde umgesetzt wird. So erlaubt das Betriebssystem, dass ein Thread "etwas länger" läuft, bis er zu einem anderen Thread wechselt (um den Einfluss der Wechselkosten zu reduzieren). Daher hängt das Ergebnis sehr davon ab, wie das Switching implementiert wird und wie groß die Aufgabe ist. Wenn die Aufgabe klein ist, könnte es sein, dass keine Umschaltung stattfindet, und in Ihrem Beispiel werden alle Threads mit niedriger Priorität zuerst beendet.

  • Bei diesen Berechnungen wurde angenommen, dass hohe und niedrige Priorität als Extremfälle interpretiert wurden. In der Tat ist Priorität eher etwas wie "In n von m Fällen bevorzugen dies" mit Variable n und m.

  • Sie haben einen Thread.yield in Ihrem Code! Dies wird die Ausführung an einen anderen Thread übergeben. Wenn Sie das zu oft tun, werden alle Threads die gleiche CPU-Leistung erhalten.

Daher würde ich nicht die Ausgabe erwarten, die Sie in Ihrer Frage erwähnt haben, nämlich dass der Thread mit hoher Priorität zuerst und dann der Thread mit niedriger Priorität endet.

Tatsächlich: Mit der Zeile Thread.yield habe ich das Ergebnis, dass jeder Thread die gleiche CPU-Zeit bekommt. Ohne die Zeile Thread.yield und die Anzahl der Berechnungen um den Faktor 10 zu erhöhen und die Anzahl der niedrigen prio-Threads um den Faktor 10 zu erhöhen, bekomme ich ein erwartetes Ergebnis, nämlich dass der high prio Thread früher um einen Faktor endet (was hängt von der Anzahl der nativen CPU-Threads ab.

    
Christian Fries 19.08.2013 07:13
quelle
1

Ich glaube, das Betriebssystem kann die Java-Thread-Priorität ignorieren.

    
jn1kk 20.08.2012 13:32
quelle
1

Threadpriorität ist ein Hinweis (der ignoriert werden kann), so dass das Betriebssystem, wenn Sie 100% CPU haben, wissen, dass Sie einige Threads gegenüber anderen bevorzugen möchten. Die Threadpriorität muss festgelegt werden, bevor der Thread gestartet oder ignoriert werden kann.

Unter Windows müssen Sie Administrator sein, um die Thread-Priorität festzulegen.

    
Peter Lawrey 20.08.2012 19:27
quelle
1

Mehrere Dinge zu beachten:

Dariusz 19.08.2013 07:27
quelle
0

Einige Betriebssysteme bieten keine ordnungsgemäße Unterstützung für Thread-Prioritäten.

    
Satyendra 30.03.2016 04:08
quelle