Каковы преимущества неблокирующего стиля? - PullRequest
0 голосов
/ 22 ноября 2018

Я пытаюсь понять основные принципы неблокирующего программирования (и таких фреймворков, как проектный реактор).Основная идея заключается в том, чтобы иметь «пул потоков» с определенным количеством потоков (исполнителей) и задач, которые там выполняются.У нас не должно быть никаких заблокированных тем.В «пользовательском коде» мы просто запускаем что-то для выполнения и оставляем обратный вызов (что делать с результатом).Наш "пользовательский" поток не заблокирован, верно.Но что, если моя задача зависит от какого-то jdbc-запроса.Моя задача запросит этот запрос и будет заблокирована в ожидании результата, верно?Итак, этот поток заблокирован.

Но мы избегаем создания потока (что дорого).Является ли это основным преимуществом этого стиля?

Если мой пул потоков состоит из 2 исполнителей и оба заблокированы в ожидании чего-то, другие задачи не будут выполнены, верно?Как этого избежать?Создать более 2-х тем?

Ответы [ 2 ]

0 голосов
/ 22 ноября 2018

Project Reactor - это реализация спецификации Reactive Streams.Обзор спецификации можно найти по адресу ReactiveManifest .Это не просто создание набора потоков и предоставление им возможности выполнять свою работу. Это среда или среда выполнения (в данном случае ProjectReactor), которая организует ваш код таким образом, что он предположительно будет вести себя как неблокирующий.Кроме того, вся реализация системы должна быть такой, иначе вы не получите выгоды от реактивных потоков.

Если мой пул потоков состоит из 2 исполнителей, и оба заблокированы в ожидании чего-либо, другиезадачи не будут выполнены, верно?Как этого избежать?Создать более 2-х тем?

Ответом будет «да» и «нет».Фреймворк может не создавать потоки.Поскольку код будет чередоваться между потоками, поскольку неблокирующая система управляется событиями, включая низкоуровневые операции (например, libuv I / O), поток не должен ждать завершения I /O операция.Между тем, поток будет выполнять что-то значимое.О завершении задачи будет сообщено, и зависимый код может быть выполнен любым доступным потоком.Цель такой системы - максимально использовать процессор при ограниченных ресурсах (потоках).

Взято из http://www.reactive -streams.org . Основная цель Reactive Streams состоит в том, чтобы управлять обменом потоковыми данными через асинхронную границу - продумывать передачу элементов в другой поток или пул потоков - при обеспечении того, чтобы принимающая сторона не была вынуждена буферизовать произвольные объемы данных.Другими словами, противодавление является неотъемлемой частью этой модели, чтобы обеспечить возможность ограничения очередей, которые являются посредниками между потоками.Преимущества асинхронной обработки были бы сведены на нет, если бы передача обратного давления была синхронной (см. Также Манифест Reactive), поэтому необходимо позаботиться о том, чтобы обеспечить полное неблокирующее и асинхронное поведение всех аспектов реализации Reactive Streams.

Это инфраструктура Reactor, которая обеспечивает и помогает вам построить полностью неблокирующую систему с нуля.

0 голосов
/ 22 ноября 2018

Потоки - это относительно дорогие системные ресурсы.Например, каждому потоку нужна память для стека вызовов.Сколько это зависит, зависит от операционной системы, но обычно это что-то вроде 1 или 2 МБ.Это означает, что запускать тысячи потоков - не очень хорошая идея - вы тратите 1 или 2 ГБ памяти только на стеки вызовов, состоящие из 1000 потоков.

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

Однако представьте, что у вас будет пул потоков с 10 потоками, а затем поступит 10 запросов. Каждый из ваших потоков будетбыть зарезервирован для обработки запроса.Пока они заняты, вы не можете обработать запрос № 11, потому что нет свободных потоков.Когда вы используете блокирующий ввод / вывод, то, хотя все ваши 10 потоков ничего не делают (ожидая завершения ввода / вывода), запрос № 11 не может быть обработан ...

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

Таким образом, при неблокирующем вводе / выводе у вас никогда не будет ожидающих потоков и вы используете системные ресурсы более эффективно.

Это будет работать только в том случае, если вы используете неблокирующий ввод / вывод.O от передней к задней части вашей системы.Если на бэкэнде вы используете JDBC, который является блокирующим API, вы потеряете все преимущества неблокирующего ввода-вывода.

Поэтому, если у вас есть база данных на бэк-сервереВ конце концов, это работает лучше всего, если у вас есть БД, которая поддерживает неблокирующий ввод / вывод.Некоторые базы данных NoSQL, такие как MongoDB, поддерживают это, а для некоторых реляционных баз данных доступны специальные драйверы / API, которые поддерживают это.В этом случае вы не будете использовать JDBC, потому что JDBC является по сути блокирующим API.

Oracle работает над новым API для реляционных баз данных, предварительно называемым ADBA , который позволит вам сделатьнеблокирующий / асинхронный ввод-вывод с реляционными базами данных, но он еще не готов.

...