您认为Scala如何帮助我们编写像Redis这样的分布式内存服务(但多线程)?
Scala编程鼓励我们使用不可变数据,以避免共享数据和竞争条件,但在这种数据存储中,不可变数据对我们没有帮助(我认为)。
阻塞线程是解决方案吗?
Scala处理不可变数据和可变数据同样好。
当然,我们非常鼓励使用不可变的数据——对于任何可以在线程/参与者之间共享的数据。
但也强烈鼓励使用专用于单个线程/参与者的可变数据,即在永远无法在线程/参与者之间共享的上下文中。
一个简单的高级并发模式是:
- 将可变数据设为每个
Actor
的私有数据:- 将可变类型专用于各个参与者
- 使用actor act/receiveve/react方法操作可变数据
- 仅在
Actor
之间共享不可变数据- 向其他参与者发送消息,但将可变数据转换为不可变数据,并且只在参与者之间发送后者
- 从不在消息中向另一个
Actor
发送对Actor
的引用- 由于(1),参与者本身变得可变
- 由于(2),它们不应该共享
- 这将阻止ActorA调用ActorB上的任何方法——所有通信都应该通过消息(方法
!
和!!
)
- 识别长时间运行的操作并使其异步。即使是超出CPU+一级缓存+二级缓存的简单操作,也可能比CPU中更快的操作慢100000s到10000000s,例如从内存读取大量数据、读取/写入磁盘、读取/写入网络-请参阅末尾的表:http://norvig.com/21-days.html
- 通常,不要阻塞异步操作——它通常会"占用"线程(消耗资源),如果设计不仔细,可能会导致死锁(运行时失败),并且总是可以以非阻塞的方式处理。如果需要处理异步响应,请让异步请求返回
Future[T]
作为启动的一部分。然后通过Future.onComplete
指定响应处理代码(或者更好的是通过Future.flatMap/Map/withFilter/Recover
和它们的for
——理解等价物——它们是方便的onComplete
的"一元"包装)