Почему не зеленые нити?

33

Хотя я знаю, что вопросы по этому вопросу уже были рассмотрены (например, https://stackoverflow.com/questions/5713142/green-threads-vs-non-green-threads ), я не чувствую, что получил удовлетворительный ответ ,

Вопрос в том, почему JVM больше не поддерживает зеленые потоки?

Об этом говорится в Java-коде в стиле кода :

Зеленый поток относится к режиму работы виртуальной машины Java (JVM), в которой весь код выполняется в одном потоке операционной системы.

И это закончилось на java.sun.com :

Недостатком является то, что использование зеленых потоков означает, что системные потоки в Linux не используются, и поэтому виртуальная машина Java не масштабируется при добавлении дополнительных процессоров.

Мне кажется, что JVM может иметь пул системных процессов, равный количеству ядер, а затем запускать зеленые потоки поверх этого. Это может дать некоторые большие преимущества, когда у вас очень большое количество потоков, которые часто блокируются (в основном потому, что текущая JVM ограничивает количество потоков).

Мысли?

redjamjar
источник
5
Мне кажется, вопрос: почему зеленые нитки? Зачем заново вводить многопоточность, эмулируя ее на уровне JVM через несколько процессов? Это большая боль и издержки для того, чтобы, казалось бы, не получить никакой выгоды, кроме как позволить программистам быть более щедрыми в порождении потоков (и я не уверен, что это преимущество).
4
Ну, речь идет о параллельной модели программирования, которая масштабируется. В настоящее время в Java, если вам нужна масштабируемость, вы переключаетесь на NIO со своим собственным пулом потоков. По крайней мере, это мое понимание.
redjamjar
3
Наличие таких вещей, как < akka.io >, которые поддерживают легкие потоки, также заставляет меня думать, что это необходимо. На самом деле, только что нашел довольно хорошее обсуждение здесь < stackoverflow.com/questions/7458782/… >
redjamjar
2
@delnan Потому что переключение контекста для собственных потоков стоит. Зеленые потоки имеют гораздо меньше накладных расходов для переключения контекста и синхронизации между процессами. Кроме того, количество зеленых потоков практически не ограничено (их могут быть сотни тысяч без особой нагрузки на процесс виртуальной машины), в то время как количество собственных потоков ограничено ОС и накладными расходами памяти.
Permeakra
Прошло много времени, прежде чем JVM напрямую поддерживала собственные потоки. Зеленые нити были промежуточным решением до тех пор.
Турбьёрн Равн Андерсен

Ответы:

29

Я помню, как JVM отказалась от зеленых нитей и перешла к родным. Это было по двум простым причинам: зеленые потоки были откровенным мусором, и была необходимость в поддержке многоядерных процессоров при ограниченных усилиях разработчиков, доступных в Sun.

Это позор - зеленые потоки обеспечивают намного лучшую абстракцию, позволяя параллелизму быть полезным инструментом, а не камнем преткновения. Но зеленые нити бесполезны, если нельзя преодолеть несколько препятствий:

  • они должны использовать все доступные им ядра процессора

  • переключение контекста должно быть дешевым

  • Ввод / вывод может блокировать любой поток, участвующий в нем, но не любой другой поток и, конечно, не все другие потоки, как это было в некоторых ранних реализациях.

Я часто задавался вопросом, почему многопоточность так сложна в Java, но теперь она становится понятнее - в конечном итоге это было связано с переходом на нативные потоки, которые:

  • хорошо использовать все ядра процессора

  • хорошо работает по-настоящему параллельно, обеспечивая независимый ввод-вывод и т. д.

  • медленный при переключении контекста (по сравнению с лучшими реализациями зеленых потоков)

  • ужасно жадный с памятью, следовательно, ограничение максимально возможного количества из них

  • плохая абстракция для какой-либо основы для выражения реального мира, что, конечно же, является весьма параллельным.

В настоящее время программисту уделяется много времени кодированию неблокирующих операций ввода-вывода, фьючерсов и т. Д. Жаль, что у нас нет лучшего уровня абстракции.

Для сравнения, кроме Erlang, новый язык Go хорошо справляется с огромным параллелизмом. Дедушка из них все еще остается Оккамом , все еще продолжающимся исследовательским проектом.

Rick-777
источник
как далеко мы продвинулись с того времени, как вы опубликовали: O
Дмитрий
3
Увы, Rust - это другой язык, который отказался от абстракций лучшей параллелизма. Они тоже решили перейти от кооперативных потоков к родным.
Рик-777
2
@ Rick-777 Rust слишком низкий уровень, чтобы сделать это.
Малкольм
15

У одного процесса, имитирующего несколько потоков, много проблем. Одним из них является то, что все поддельные темы останавливаются на любой странице ошибки.

Альтернатива, которую вы предлагаете, пул процессов, имеет некоторые преимущества и недостатки. Самое большое преимущество, изоляция «нитей», действительно не принесет вам многого. Большой недостаток, чрезвычайная сложность реализации и менее эффективная синхронизация - вот что мешает совершить сделки.

Однако я согласен с тем, что существуют некоторые приложения (не Java), в которых было бы неплохо иметь пул процессов, которые вы могли бы использовать как пул потоков (но с большей изоляцией). Темы делятся практически всем. С помощью процессов вы можете конкретно выбрать, чем поделиться. Насколько мне известно, никто еще не приложил усилий для его реализации.

Дэвид Шварц
источник
Оккам утверждает, что предложил это. Это был важный язык в 80-х, но он страдал от недостатка финансирования развития и, следовательно, стал только исследовательской нишей. Но его идеи о параллелизме сейчас так же прочны, как и тогда, и их еще предстоит улучшить.
Рик-777
Если вы «многопоточные» по-другому (планирование типа «M: N»), то теоретически только один зеленый поток блокируется ошибкой страницы, потому что другие потоки могут «устранить слабину» (другие зеленые потоки), как кажется. .. softwareengineering.stackexchange.com/questions/222642/...
rogerdpack
13

Для обычного Java-кода никакой выгоды не будет. Java - это не Erlang, и программисты на Java не так настроены, как программисты на Erlang. Язык никогда не предназначался для использования таким образом.

Если вы хотите по-настоящему легкие процессы - используйте Erlang и создайте тысячи потоков, обменивающихся сообщениями. В Java у вас будет дюжина потоков, разделяющих общую память с мьютексами и семафорами. Это просто другая модель программирования, предназначенная для другого набора задач.

SK-логика
источник
Таким образом, чтобы уточнить, хотя это полезный подход в Erlang. И, игнорируя проблемы мышления Java, это действительно может помочь?
redjamjar
1
@redjamjar, вряд ли он будет полезен в Java, сам язык не совсем подходит для такого использования, и его основное (и единственное) преимущество - обширный массив готовых к использованию библиотек - не очень хорошо вписывается в такого инопланетянина программный подход.
SK-logic
Да, если вы хотите эту модель, просто используйте Erlang, это будет на порядок проще
Захари К
1
Java! = JVM, просто говорю :)
Камиль Томшик
1
@ Бэйн, эти «преимущества» существуют только в том случае, если тебе не с чем сравнивать
SK-logic