Реактивное программирование против программирования на основе потоков

#java #multithreading #rx-java #reactive-programming #spring-webflux

Вопрос:

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

Давайте рассмотрим сценарий узла JS, который является однопоточным и обеспечивает быструю работу ввода-вывода с использованием цикла событий. Теперь это имеет смысл, поскольку он однопоточный и не блокируется ни для одной задачи.

Во время изучения реактивного программирования на Java с использованием reactor. Я попал в ситуацию, когда основной поток блокируется при подписке объекта и произошло какое-то событие задержки. Затем я познакомился с концепцией subscribeOn.boundedElastic и многими другими подобными конвейерами.

Я понял, что они пытаются сделать его асинхронным, переместив этих подписчиков в другие потоки.

Но если это происходит так, то почему происходит асинхронно? Разве это не потоковое программирование? Если мы пытаемся добиться асинхронного поведения узла JS, то, на мой взгляд, это должно быть в одном потоке.

Краткое изложение моего вопроса таково:

Поэтому я не понимаю факта использования или вызова реактивного программирования как асинхронного или функционального программирования по двум причинам

  1. Основной поток заблокирован
  2. Мы можем управлять потоком и запускать его в другом пуле. Управляемая служба/ вызываемая, которую мы также можем определить.

Комментарии:

1. Традиционно JVM основана на потоках. При выполнении реактивных действий основное недоразумение, которое у вас осталось, заключается в том, что при использовании модели на основе потоков у вас есть гарантия того, что запрос обрабатывается одним потоком и он не изменяется, в то время как в реактивном стеке нет гарантии, что это тот же поток, который сначала работает с запросом, а затем может быть приостановлен. Позже другой поток может продолжить работу над запросом.

Ответ №1:

Во-первых, вы не можете сравниться asynchronous с functional programming . Это все равно что сравнивать камень с бананом. Это две разные вещи.

Functional programming сравнивается с другими типами программирования, такими как object oriented programming или procedural programming и т. Д. и т. Д.

Reactor-это библиотека java, а java-это объектно-ориентированный язык программирования с функциональными возможностями.

Asynchronous я объясню с помощью того, что говорит википедия

Асинхронность в компьютерном программировании относится к возникновению событий, независимых от основного потока программы, и способов борьбы с такими событиями.

Таким образом, в основном то, как обрабатывать материалы «вокруг» вашего приложения, не является частью основного потока вашей программы.

По сравнению с Blocking википедией снова:

Заблокированный процесс-это процесс, который ожидает какого-либо события, такого как доступ к ресурсу или завершение операции ввода-вывода.

Традиционное приложение-сервлет работает, назначая один поток на запрос.

Поэтому каждый раз, когда поступает запрос, создается поток, и этот поток следует за запросом до тех пор, пока запрос не вернется. Если во время этого запроса что-то блокируется, например, чтение файла из операционной системы или отправка запроса в другую службу. Назначенный поток заблокируется и будет ждать, пока чтение файла не будет завершено, или запрос не вернется и т.д.

Реактивная работа с subscribers и producers и интенсивно использует observer pattern . Это означает, что, как только что-то блокируется, реактор может взять этот поток и использовать его для чего-то другого. И тогда он не блокируется, любой поток может продолжить с того места, на котором он остановился. Это гарантирует, что каждый поток всегда используется и используется на 100%.

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

Если вы просто запустите reactor, вы получите планировщик по умолчанию, который будет планировать все для вас полностью автоматически.

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

Когда вы запускаете полностью реактивное приложение, вы обычно получаете один цикл событий на ядро во время запуска. Это означает, что, допустим, у вас 4 ядра, вы получаете 4 цикла событий и блокируете один, затем в течение этого периода блокировок ваше приложение работает на 25% медленнее.

На 25% медленнее-это много!

Ну, иногда у вас есть что-то блокирующее, чего вы не можете избежать. Например, старая база данных, в которой нет неблокирующего драйвера. Или вам нужно прочитать файлы из операционной системы в режиме блокировки. Как вы тогда поживаете?

Что ж, команда reactor создала резервный вариант, так что если вы используете onSubscribe его в сочетании с собственным пулом эластичных потоков, то вы вернете старое поведение сервлета для этого единственного подписчика к определенной конечной точке и т. Д.

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

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

Комментарии:

1. спасибо за подробное объяснение. и да, простите меня, пока я писал асинхронное и функциональное программирование вместе. Таким образом, в основном вы пытаетесь сказать, что нам не нужно управлять потоками, если мы создаем реактивное приложение. мы начнем управлять потоками, когда у нас будет некоторый устаревший код(например), чтобы заставить его вести себя асинхронно.

2. Я ничего не говорю об управлении потоками. Все зависит от конкретного случая пользователя.