Модель актора работает с передачей сообщений. Отдельным процессам (субъектам) разрешено отправлять сообщения друг другу асинхронно. Что отличает это от того, что мы обычно называем потоковой моделью, так это то, что здесь нет (по крайней мере теоретически) общего состояния. И если кто-то считает (я думаю, что это вполне оправданно), что разделяемое состояние является корнем всех зол, то модель акторов становится очень привлекательной.
Однако нам не следует слишком волноваться. Модель акторов не исключает (вопреки некоторым утверждениям) тупиковых ситуаций. Модель акторов также не предотвращает конкуренции за ресурсы между различными процессами - например, очередями сообщений. Модель "без блокировки" только выше определенного уровня. На более низком уровне для координации очередей сообщений по-прежнему требуется блокировка.
Разве поток нельзя рассматривать как актера и отправлять сообщения другим потокам?
Ну да и нет. Нет, если вы просто используете подход размещения мьютексов вокруг общих областей памяти. Затем потоки разделяют это состояние - они оба имеют доступ к этой памяти, могут читать ее, перезаписывать и т. Д. Но вы можете построить модель актора поверх модели потоковой передачи, и действительно, у всех реализаций акторов есть потоки под. Я сделал что-то вроде этого (очень плохо), предоставив каждому потоку очередь, охраняемую мьютексом - просто для удовольствия. Чтобы получить представление о том, как регулируется импеданс актор-нить, см. Мой вопрос год назад .
Могу ли я использовать модель актера на любом языке, используя потоки по-разному?
Да, но потребуется немного больше работы. Ваш любимый язык вполне может иметь библиотеку передачи сообщений, так что это будет первое, что нужно исследовать. Кроме того, вам следует изучить использование неизменяемых структур данных. Обратите внимание: если структура данных неизменяема, то вы, по сути, столкнулись с проблемой «общего состояния» - несколько потоков могут хранить ссылки на неизменяемые данные без каких-либо проблем. Есть причина, по которой языки-акторы, как правило, также являются функциональными языками (erlang, scala).
Вы также можете взглянуть на программную транзакционную память, которая представляет собой другую, но также интересную модель. Clojure - мой любимый пример.
Я бы не сказал, что акторы всегда передают сообщения асинхронно - это было бы слишком медленно. В частности, проект JActor использует двусторонние сообщения (запрос / ответ) для лучшего моделирования вызова метода. И большинство запросов обслуживаются синхронно.
JActor (библиотека Java) также не использует блокировки. Только некоторые атомарные и параллельные структуры данных с добавлением нескольких семафоров. Передача сообщений составляет около 0,8 миллиарда сообщений в секунду.
https://github.com/laforge49/JActor
источник