首先,我有很多 Java 经验,但是最近才对函数式语言感兴趣。最近我开始研究 Scala,它似乎是一种非常好的语言。
然而,我一直在阅读关于 用 Scala 编程中 Scala 的 Actor 框架,有一件事我不明白。在第30.4章中,它说使用 react
而不是 receive
可以重用线程,这对性能有好处,因为线程在 JVM 中是昂贵的。
这是否意味着,只要我记得调用 react
而不是 receive
,我就可以随心所欲地启动多个 Actor?在发现 Scala 之前,我一直在使用 Erlang,而且 编程 Erlang的作者吹嘘自己不费吹灰之力就产生了超过200,000个进程。我讨厌对 Java 线程这么做。与 Erlang (和 Java)相比,我在 Scala 中看到了什么样的限制?
此外,这个线程在 Scala 中是如何重用的?为了简单起见,假设我只有一个线程。我开始运行的所有参与者会在这个线程中顺序运行,还是会发生某种任务切换?例如,如果我启动两个参与者,乒乓消息互相发送,如果它们在同一个线程中启动,我会冒死锁的风险吗?
根据 Scala 编程,编写演员使用 react
比使用 receive
更困难。这听起来似乎有道理,因为 react
不会返回。然而,本书继续展示了如何使用 Actor.loop
将 react
放入一个循环中。结果,你得到了
loop {
react {
...
}
}
在我看来
while (true) {
receive {
...
}
}
这在书的前面已经用过了。尽管如此,这本书说“在实践中,程序将至少需要几个 receive
”。我错过了什么?除了返回,receive
还能做什么 react
不能做的?关我什么事?
最后,来到我不理解的核心: 这本书一直在提到如何使用 react
使得丢弃调用堆栈来重用线程成为可能。这是怎么回事?为什么必须丢弃调用堆栈?为什么当函数通过抛出异常(react
)结束时可以丢弃调用堆栈,而当函数通过返回(receive
)结束时不能丢弃调用堆栈?
我的印象是,Scala 编程一直在掩盖这里的一些关键问题,这是一个耻辱,因为否则它是一本真正优秀的书。