Позвольте мне сначала сказать, что у меня довольно много опыта Java, но только недавно заинтересовались функциональными языками. Недавно я начал смотреть на Scala, который кажется очень приятным языком.
Однако, я читал о Scala структуре Actor в Программирование в Scala, и там одна вещь, которую я не делаю Понимаю. В главе 30.4 говорится, что использование react
вместо receive
позволяет повторно использовать потоки, что хорошо для производительности, поскольку потоки дороги в JVM.
Означает ли это, что до тех пор, пока я не помню, чтобы позвонить react
вместо receive
, я могу запустить столько актеров, сколько мне нравится? Прежде чем открыть Scala, я играл с Erlang, а автор Programming Erlang может похвастаться тем, что он размножил более 200 000 процессов, не нарушая пота. Я бы не хотел этого делать с потоками Java. Какие ограничения я рассматриваю в Scala по сравнению с Erlang (и Java)?
Также, как этот поток повторно использует работу в Scala? Пусть для простоты предположим, что у меня есть только один поток. Будут ли все актеры, которые я запускаю последовательно в этом потоке, или произойдет какое-то переключение задач? Например, если я начну с двумя актерами, которые пинг-понг сообщения друг к другу, я буду рисковать тупиком, если они запущены в том же потоке?
Согласно Программе в Scala, писать актеров для использования react
сложнее, чем с receive
. Это звучит правдоподобно, так как react
не возвращается. Тем не менее, в книге далее показано, как вы можете положить react
внутри цикла, используя Actor.loop
. В результате вы получаете
loop {
react {
...
}
}
который для меня кажется очень похожим на
while (true) {
receive {
...
}
}
который используется ранее в книге. Тем не менее, в книге говорится, что "на практике программам потребуется по крайней мере несколько receive
". Так что мне здесь не хватает? Что может receive
сделать, что react
не может, кроме возврата? И почему меня это волнует?
Наконец, в основе я не понимаю: в книге упоминается, как использование react
позволяет отбросить стек вызовов для повторного использования потока. Как это работает? Почему необходимо отбрасывать стек вызовов? И почему стек вызовов может быть отброшен, когда функция завершается, вызывая исключение (react
), но не когда оно завершается возвратом (receive
)?
У меня создалось впечатление, что программирование в Scala замаскировало некоторые из ключевых проблем здесь, что является позором, потому что в противном случае это действительно отличная книга.