Warum nicht Green Threads?

33

Obwohl ich weiß, dass Fragen hierzu bereits beantwortet wurden (z. B. https://stackoverflow.com/questions/5713142/green-threads-vs-non-green-threads ), habe ich keine zufriedenstellende Antwort .

Die Frage ist: Warum unterstützt JVM keine grünen Fäden mehr?

In der Java-FAQ im Codestil heißt es :

Ein grüner Thread bezieht sich auf einen Betriebsmodus für die Java Virtual Machine (JVM), in dem der gesamte Code in einem einzigen Betriebssystem-Thread ausgeführt wird.

Und das auf java.sun.com :

Der Nachteil ist, dass die Verwendung von grünen Threads bedeutet, dass System-Threads unter Linux nicht ausgenutzt werden und die Java Virtual Machine daher nicht skalierbar ist, wenn zusätzliche CPUs hinzugefügt werden.

Es scheint mir, dass die JVM einen Pool von Systemprozessen haben könnte, der der Anzahl der Kerne entspricht, und dann grüne Threads darüber laufen lassen. Dies könnte einige große Vorteile bieten, wenn Sie eine sehr große Anzahl von Threads haben, die häufig blockieren (hauptsächlich, weil aktuelle JVMs die Anzahl der Threads begrenzen).

Gedanken?

redjamjar
quelle
5
Mir scheint die Frage: Warum grüne Fäden? Warum sollte Multithreading wieder eingeführt werden, indem es über mehrere Prozesse auf JVM-Ebene emuliert wird? Es ist eine Menge Aufwand für scheinbar keinen anderen Gewinn, als es Programmierern zu ermöglichen, großzügiger mit Laichfäden umzugehen (und ich bin nicht davon überzeugt, dass dies ein Vorteil ist).
4
Nun, es geht darum, ein paralleles Programmiermodell zu haben, das skaliert. Wenn Sie derzeit in Java Skalierbarkeit wünschen, wechseln Sie mit Ihrem eigenen Thread-Pool zu NIO. Zumindest ist das mein Verständnis.
Redjamjar
3
Das Vorhandensein von Dingen wie < akka.io >, die Lightweight-Threads unterstützen, lässt mich auch vermuten , dass Bedarf besteht. Ich fand gerade eine gute Diskussion hier < stackoverflow.com/questions/7458782/… >
Redjamjar
2
@delnan Weil Kontextwechsel für native Threads kosten. Grüne Threads haben viel weniger Overhead für Kontextwechsel und Interprozesssynchronisierungen. Darüber hinaus ist die Anzahl der grünen Threads praktisch unbegrenzt (sie können Hunderttausende sein, ohne dass der VM-Prozess zu stark belastet wird), während die Anzahl der systemeigenen Threads durch das Betriebssystem und den Arbeitsspeicher begrenzt wird.
Permeakra
Es dauerte lange, bis die JVM native Threads direkt unterstützte. Grüne Fäden waren bis dahin die Zwischenlösung.
Thorbjørn Ravn Andersen

Antworten:

29

Ich erinnere mich, dass die JVM grüne Threads aufgegeben und zu nativen Threads gewechselt hat. Dies hatte zwei einfache Gründe: Die grünen Threads waren ehrlich gesagt Müll, und es bestand die Notwendigkeit, Multi-Core-Prozessoren mit dem begrenzten Entwicklungsaufwand von Sun zu unterstützen.

Dies war eine Schande - grüne Fäden bieten eine weitaus bessere Abstraktion, so dass Parallelität ein nützliches Werkzeug ist und kein Stolperstein. Aber grüne Fäden nützen nichts, wenn mehrere Hürden nicht überwunden werden können:

  • Sie müssen alle ihnen zur Verfügung stehenden CPU-Kerne verwenden

  • Kontextwechsel muss billig sein

  • I / O blockiert möglicherweise alle Threads, die daran beteiligt sind, aber nicht alle anderen Threads und schon gar nicht alle anderen Threads, was in einigen frühen Implementierungen der Fall war.

Ich habe mich oft gefragt, warum Multithreading in Java so schwierig ist, aber es wird jetzt klarer - letztendlich lag es an der Umstellung auf native Threads:

  • gut bei der Verwendung aller CPU-Kerne

  • gut darin, wirklich gleichzeitig zu sein und unabhängige E / A usw. bereitzustellen

  • Langsam beim Kontextwechsel (im Vergleich zu den besten Green-Thread-Implementierungen)

  • schrecklich gierig mit dem Gedächtnis, folglich die maximal verwendbare Anzahl von ihnen begrenzend

  • Eine schlechte Abstraktion für jede Grundlage, um die reale Welt auszudrücken, was natürlich sehr gleichzeitig ist.

Heutzutage wird viel Zeit für Programmierer aufgewendet, um nicht blockierende E / A, Futures usw. zu codieren. Es ist eine große Schande, dass wir kein besseres Abstraktionsniveau haben.

Zum Vergleich: Neben Erlang leistet die neue Sprache Go auch einen guten Job bei enormen Nebenläufigkeiten. Der Großvater von allen bleibt Occam , ein noch laufendes Forschungsprojekt.

Rick-777
quelle
Wie weit sind wir seit
Dmitry
3
Leider ist Rust eine andere Sprache, die bessere Nebenläufigkeitsabstraktionen aufgegeben hat. Auch sie beschlossen, von kooperativen zu nativen Threads zu wechseln.
Rick-777
2
@ Rick-777 Rust ist zu leise, um das zu tun.
Malcolm
15

Ein einzelner Prozess, der mehrere Threads fälscht, hat viele Probleme. Eine davon ist, dass alle gefälschten Threads bei einem Seitenfehler hängen bleiben.

Die von Ihnen vorgeschlagene Alternative, ein Pool von Prozessen, hat einige Vor- und einige Nachteile. Der größte Vorteil, die Isolierung der "Fäden", würde Sie wirklich nicht viel herbringen. Der große Nachteil, die extreme Schwierigkeit der Implementierung und die weniger effiziente Synchronisation ist der Deal-Killer.

Ich stimme jedoch zu, dass es einige Anwendungen gibt (nicht Java), in denen ein Pool von Prozessen, den Sie wie einen Pool von Threads verwenden könnten (aber mit mehr Isolation), eine großartige Sache wäre. Threads teilen so ziemlich alles. Bei Prozessen können Sie gezielt auswählen, was Sie freigeben möchten. Meines Wissens hat sich noch niemand die Mühe gemacht, es umzusetzen.

David Schwartz
quelle
Occam behauptet, dies anzubieten. Es war eine bedeutende Sprache in den 80er Jahren, litt jedoch unter dem Mangel an Entwicklungsfinanzierung und wurde folglich nur zu einer Forschungsnische. Aber seine Vorstellungen zur Parallelität sind heute so solide wie damals und müssen noch verbessert werden.
Rick-777
Wenn Sie a la golang "multi-threaded" sind ("M: N" -Typ Scheduling), wird theoretisch nur ein grüner Thread durch einen Seitenfehler blockiert, da die anderen Threads anscheinend "das Durchhängen" (andere grüne Threads) aufnehmen können. .. softwareengineering.stackexchange.com/questions/222642/…
Rogerdpack
13

Für einen durchschnittlichen Java-Code gibt es überhaupt keinen Vorteil. Java ist nicht Erlang, und Java-Programmierer sind nicht mit Erlang-Programmierern identisch. Die Sprache sollte niemals so verwendet werden.

Wenn Sie die echte Leichtgewichtigkeit von Prozessen wünschen, verwenden Sie Erlang und erstellen Sie Tausende von Threads, die über Nachrichten kommunizieren. In Java gibt es ein Dutzend Threads, die sich einen gemeinsamen Speicher mit Mutexen und Semaphoren teilen. Es ist nur ein anderes Programmiermodell, das für eine andere Reihe von Problemen entwickelt wurde.

SK-Logik
quelle
Zur Verdeutlichung ist dies in Erlang ein nützlicher Ansatz. Und wenn man die Probleme der Java-Denkweise ignoriert, könnte es tatsächlich helfen?
Redjamjar
1
@redjamjar, es ist unwahrscheinlich, dass es in Java nützlich ist, die Sprache selbst ist für eine solche Verwendung nicht ganz geeignet, und ihr Hauptvorteil (und einziger Vorteil) - die Unmenge gebrauchsfertiger Bibliotheken - passt nicht gut in solch ein Alien Programmieransatz.
SK-logic
Ja, wenn Sie dieses Modell wollen, verwenden Sie einfach Erlang, es wird eine Größenordnung einfacher sein
Zachary K
1
Java! = JVM, nur sagen :)
Kamil Tomšík
1
@Bane, diese "Vorteile" gibt es nur, wenn du nichts zu vergleichen hast
SK-logic