Obwohl ich weiß, dass Fragen dazu bereits behandelt wurden (z. B. https://stackoverflow.com/questions/5713142/green-threads-vs-non-green-threads ), ich habe nicht das Gefühl, eine zufriedenstellende Antwort erhalten zu haben.
Die Frage ist: Warum unterstützt JVM keine grünen Threads mehr?
Dies steht in der Java-FAQ im Codestil :
Ein grüner Thread bezieht sich auf einen Betriebsmodus für die Java Virtual Machine (JVM), in dem der gesamte Code in einem einzelnen Betriebssystem-Thread ausgeführt wird.
Und dies ist vorbei an java.sun.com :
Der Nachteil ist, dass die Verwendung grüner Threads bedeutet, dass Systemthreads unter Linux nicht ausgenutzt werden und die virtuelle Java-Maschine 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 darüber grüne Threads ausführen könnte. 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?
Kommentare
- Für mich scheint die Frage: Warum grüne Threads? Warum Multithreading wieder einführen, indem es auf JVM-Ebene über mehrere Prozesse emuliert wird? Es ‚ ist eine Menge Schmerz und Aufwand für scheinbar keinen anderen Gewinn, als es Programmierern zu erlauben, großzügiger mit Laich-Threads umzugehen (und ich ‚ bin nicht davon überzeugt, dass ‚ ist ein Vorteil).
- Nun, ‚ geht es um ein gleichzeitiges Programmiermodell, das skaliert. Derzeit in Java, wenn Sie Skalierbarkeit wünschen Sie wechseln mit Ihrem eigenen Thread-Pool zu NIO. Zumindest ist das ‚ mein Verständnis.
- Das Vorhandensein von Dingen wie < akka.io > welche Annahme rts leichte Fäden lassen mich auch denken, dass es einen Bedarf gibt. Eigentlich habe ich hier gerade eine ziemlich gute Diskussion gefunden < stackoverflow.com/questions/7458782/… >
- @delnan Da der Kontextwechsel für native Threads Kosten verursacht. Grüne Threads haben viel weniger Overhead für Kontextwechsel- und Interprozesssynchronisierungen. Darüber hinaus ist die Anzahl der grünen Threads praktisch unbegrenzt (es können Hunderttausende von ihnen sein, ohne dass der VM-Prozess zu stark belastet wird), während die Anzahl der nativen Threads durch das Betriebssystem und den Speicheraufwand begrenzt ist.
- Es hat lange gedauert, bis die JVM native Threads direkt unterstützte. Grüne Threads waren bis dahin die Zwischenlösung.
Antwort
Ich erinnere mich, dass die JVM grüne Threads aufgegeben und zu gewechselt hat native Threads. Dies hatte zwei einfache Gründe: Die grünen Threads waren offen gesagt Müll, und es bestand die Notwendigkeit, Multi-Core-Prozessoren mit dem begrenzten Entwickleraufwand zu unterstützen, der bei Sun verfügbar ist.
Dies war eine Schande – grüne Threads bieten eine weitaus bessere Abstraktion, so dass Parallelität ein nützliches Werkzeug und kein Stolperstein ist. Grüne Fäden nützen jedoch 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
-
E / A kann jeden daran beteiligten Thread blockieren, aber keinen anderen Thread und schon gar nicht alle anderen Threads Dies war in einigen frühen Implementierungen der Fall.
Ich habe mich oft gefragt, warum Multithreading in Java so schwierig ist, aber es wird jetzt klarer – es war letztendlich Dies hängt mit dem Wechsel zu nativen Threads zusammen, die:
-
gut darin sind, alle CPU-Kerne zu verwenden
-
gut darin, wirklich zu sein gleichzeitig, Bereitstellung unabhängiger E / A usw.
-
langsam beim Kontextwechsel (im Vergleich zu den besten Green-Thread-Implementierungen)
-
schrecklich gierig nach Gedächtnis, wodurch die maximal nutzbare Anzahl von ihnen begrenzt wird
-
eine schlechte Abstraktion für jede Grundlage zum Ausdrücken der realen Welt, die natürlich sehr gleichzeitig ist.
Heutzutage a viel Programmiererzeit fließt jetzt in das Codieren nicht blockierender E / A, Futures usw. Es ist eine große Schande, dass wir keinen besseren Abstraktionsgrad haben.
Für Vergleich: Neben Erlang leistet die neue Sprache Go gute Arbeit bei großer Parallelität. Der Großvater von allen bleibt Occam , ein noch laufendes Forschungsprojekt.
Kommentare
- Wie weit sind wir seit Ihrer Veröffentlichung gegangen: O
- Leider ist Rust eine andere Sprache, die bessere Parallelitätsabstraktionen aufgegeben hat. Auch sie haben beschlossen, von kooperativen Threads zu nativen Threads zu wechseln.
- @ Rick-777 Rust ist zu niedrig, um dies zu tun.
Antwort
Ein einzelner Prozess, der mehrere Threads fälscht, hat viele Probleme. Eine davon ist, dass alle gefälschten Threads bei jedem Seitenfehler zum Stillstand kommen.
Die von Ihnen vorgeschlagene Alternative, ein Pool von Prozessen, hat einige Vor- und einige Nachteile. Der größte Vorteil, die Isolierung der „Threads“, würde Sie hier wirklich nicht viel bringen. Der große Nachteil, die extreme Schwierigkeit der Implementierung und die weniger effiziente Synchronisation sind hier der Deal-Killer.
Ich jedoch Stimmen Sie zu, dass es einige Anwendungen gibt (nicht Java), in denen ein Pool von Prozessen, die Sie wie einen Pool von Threads verwenden könnten (aber mit mehr Isolation), eine großartige Sache wäre. Threads teilen so ziemlich alles. Mit Prozessen können Sie Wählen Sie speziell aus, was Sie teilen möchten. Meines Wissens hat sich noch niemand die Mühe gemacht, es zu implementieren.
Kommentare
- Occam behauptet, dies anzubieten. Es war eine bedeutende Sprache in den ‚ 80er Jahren, litt jedoch unter mangelnder Entwicklungsfinanzierung und wurde folglich nur zu einer Forschungsnische. Aber seine Ideen zur Parallelität sind heute so solide wie damals und damals müssen noch verbessert werden.
- Wenn Sie “ Multithreaded “ al Ein Golang (“ M: N “ Typ-Planung), dann wird theoretisch nur ein grüner Thread durch einen Seitenfehler blockiert, da die anderen Threads dies können “ nimm den Durchhang auf “ (andere grüne Fäden) es scheint … softwareengineering.stackexchange.com/questions/222642/…
Antwort
Ein durchschnittlicher Java-Code hat überhaupt keinen Vorteil. Java ist kein Erlang, und Java-Programmierer sind nicht in der gleichen Denkweise wie Erlang-Programmierer. Die Sprache sollte niemals so verwendet werden.
Wenn Sie die wirklich leichte Prozessess wollen, verwenden Sie Erlang und erstellen Sie Tausende von Threads, die über Nachrichten kommunizieren. In Java haben Sie ein Dutzend Threads, die einen gemeinsamen Speicher mit Mutexen und Semaphoren teilen. Es ist nur ein anderes Programmiermodell, das für eine andere Reihe von Problemen entwickelt wurde.
Kommentare
- Zur Verdeutlichung ist dies jedoch ein nützlicher Ansatz in Erlang. Wenn Sie die Probleme der Java-Denkweise ignorieren, könnte dies tatsächlich helfen?
- @redjamjar, ist dies unwahrscheinlich Um in Java nützlich zu sein, ist die Sprache selbst für eine solche Verwendung nicht ganz geeignet, und ihr Haupt- (und einziger) Vorteil – die große Anzahl gebrauchsfertiger Bibliotheken – passt nicht ‚ gut in solch einen fremden Programmieransatz.
- Ja, wenn Sie dieses Modell wollen, verwenden Sie einfach Erlang, es wird eine Größenordnung einfacher sein
- Java! = JVM, nur sagen 🙂
- @Bane, diese “ Vorteile “ bestehen nur, wenn Sie ‚ Ich habe nichts zu vergleichen