Scala 共享风险值安全吗?

Scala 共享风险值安全吗?,scala,akka,actor,Scala,Akka,Actor,我的应用程序有一个没有可变成员的类ApplicationUsers。创建实例后,它将整个用户数据库(相对较小)读入一个不可变的集合。它有许多方法来查询数据 我现在面临的问题是必须创建新用户(或修改其某些属性)。我目前的想法是使用一个Akka演员,在高水平上,看起来像这样: class UserActor extends Actor{ var users = new ApplicationUsers def receive = { case GetUsers => send

我的应用程序有一个没有可变成员的类
ApplicationUsers
。创建实例后,它将整个用户数据库(相对较小)读入一个不可变的集合。它有许多方法来查询数据

我现在面临的问题是必须创建新用户(或修改其某些属性)。我目前的想法是使用一个Akka演员,在高水平上,看起来像这样:

class UserActor extends Actor{
  var users = new ApplicationUsers

  def receive = {
    case GetUsers => sender ! users

    case SomeMutableOperation => {
      PerformTheChangeOnTheDatabase() // does not alter users (which is immutable)
      users = new ApplicationUsers // reads the database from scratch into a new immutable instance
    }
  }
}
这安全吗?我的推理是:只要
users
SomeMutableOperation
更改,使用
users
以前实例的任何其他线程都已经拥有旧版本的句柄,并且不应受到影响。此外,任何
GetUsers
请求在新实例未安全构建之前都不会被执行

我有什么遗漏吗?我的建筑安全吗


更新:我可能应该用它来做这件事,但问题仍然是:上面的东西安全吗?

我觉得很好。你们这里似乎不需要代理。

我觉得不错。您在这里似乎不需要代理。

您做得完全正确:拥有不可变的数据类型,并通过actor中的
var
引用它们。通过这种方式,您可以自由地共享数据,并且易变性仅限于参与者。唯一需要注意的是,如果您引用了在参与者之外执行的闭包中的
var
(例如,在
未来的
转换或
道具
实例中)。在这种情况下,需要制作堆栈本地副本:

val currentUsers=用户
其他的?进程(用户)recoverWith{case}=>backup?进程(currentUsers)}

在第一种情况下,您只需获取值,这很好,但请求备份是从不同的线程进行的,因此需要
val currentUsers

您做得非常正确:拥有不可变的数据类型,并通过actor中的
var
引用它们。通过这种方式,您可以自由地共享数据,并且易变性仅限于参与者。唯一需要注意的是,如果您引用了在参与者之外执行的闭包中的
var
(例如,在
未来的
转换或
道具
实例中)。在这种情况下,需要制作堆栈本地副本:

val currentUsers=用户
其他的?进程(用户)recoverWith{case}=>backup?进程(currentUsers)}

在第一种情况下,您只需获取值,这很好,但请求备份是从不同的线程进行的,因此需要
val currentUsers

谢谢。我认为代理可以简化我的代码(无需创建上述结构),并且还可以自然地将数据库的更新与
用户
对象的更新分开,在我的情况下,这将是一个更好的设计。我认为代理的问题是,它们只是您正在运行的节点(jvm)的本地。不能将它们远程传递给其他节点。当您想扩展系统时,这可能会产生问题。谢谢。我认为代理可以简化我的代码(无需创建上述结构),并且还可以自然地将数据库的更新与
用户
对象的更新分开,在我的情况下,这将是一个更好的设计。我认为代理的问题是,它们只是您正在运行的节点(jvm)的本地。不能将它们远程传递给其他节点。当您想要扩展系统时,这可能会产生问题。