Процесс Erlang против потока Java



Я читаю книга Саши Юрича "эликсир в действии", и в первой главе Он говорит:




процессы Эрланга полностью изолированы друг от друга. Они делятся
нет памяти, и сбой одного процесса не вызывает сбоя другого
процессы.




разве это не верно и для Java-потоков? Я имею в виду, когда поток Java падает, он тоже не разбивает другие потоки-особенно, если мы смотрим на потоки обработки запросов (давайте исключим main нить из этой дисукции)

496   6  

6 ответов:

повторяйте за мной: "это разные парадигмы"

Если мы действительно должны сравнить яблоки и апельсины, давайте хотя бы рассмотрим, где пересекаются общие аспекты "быть фруктами".

Java "объекты" являются основной единицей вычислений Java-программиста. То есть,объект (в основном структура с руками и ногами, которая имеет инкапсуляцию несколько более строго, чем в C++) является основным инструментом, с помощью которого вы моделируете мир. Вы думаете :" этот объект знает / имеет Data {X,Y,Z} и осуществляет Functions {A(),B(),C()} над ним, несет Data везде он идет, и может взаимодействовать с другими объектами, вызывая функции/методы, определенные как часть их публичного интерфейса. Это существительное, и это существительное тут вещи.". То есть, вы ориентируете свой мыслительный процесс вокруг этих единиц расчета. Неисполнение дело в том, что вещи, которые происходят среди объектов, происходят последовательно, и сбой прерывает эту последовательность. Они называются "объектами", и поэтому (если мы игнорируем первоначальное значение Алана Кея) мы получаем"объектную ориентацию".

Erlang "процессы" являются основной единицей вычислений программиста Erlang. А

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

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

Elixir / Erlang, с другой стороны, обращается к этому понятию неизменности, поэтому, когда вы передаете что-то процессу, это будет копия исходного значения.

когда поток Java умирает, он тоже не влияет на другие потоки

позвольте мне задать встречный вопрос: почему вы думаете Thread.stop() был осужден более десяти лет? Почему именно отрицание вашего утверждения выше.

приведу два конкретных примера: вы stop() поток, когда он выполняет что-то столь же безобидное, как System.out.println() или Math.random(). Результат: эти две функции теперь нарушены для всей JVM. Тот же относится к любому другому синхронизированному коду, который может выполняться вашим приложением.

если мы смотрим на потоки обработки запросов

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

чтобы дополнить предыдущие ответы, потоки Java есть два типа: демон и не демон.

изменить тип потока вы можете позвонить .setDaemon(boolean on). Разница в том, что поток демона не удерживает JVM от выхода. Как говорит Javadoc для потока:

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

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

что касается сравнения с Erlang / Elixir не забывайте:это разные парадигмы, как уже говорилось.

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

разве это не верно и для Java-потоков? Я имею в виду, когда поток Java падает, он тоже не разбивает другие потоки

да и нет. Я объясняю:

  • ссылаясь на общую память: различные потоки в процессе Java разделяют всю кучу, поэтому потоки могут взаимодействовать в огромном количестве запланированных и незапланированных способов. объекты в стеке (например, контекст, который вы передаете вызываемому методу) или ThreadLocal несколько их собственный поток (если они не начнут делиться ссылками).

  • сбой: если поток аварийно завершает работу в Java (a Throwable передается в Thread.run(), или что-то зацикливается или блокируется), что неудача не может повлиять на другие потоки (например, пул соединений на сервере будет продолжать работать). как взаимодействуют различные потоки. Другие потоки легко сядут на мель, если один из них заканчивается ненормально (например, один поток пытается прочитать из пустой трубы из другой нити, которая не закрывала свой конец). Так что если разработчики не очень паранойя осторожно, это очень вероятно, что побочные эффекты будут происходить.

Я сомневаюсь, что любая другая парадигма предполагает, что потоки будут работать как полностью независимые острова. Они должны делиться информацией и как-то координировать свои действия. И тогда появится шанс все испортить. Это просто они будут более оборонительный подход, который "дает вам меньше веревки, чтобы повеситься" (та же идиома, что и с указателями).

Comments

    Ничего не найдено.