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