共享var是否安全?

时间:2013-05-11 06:51:44

标签: scala akka actor

我的应用程序有一个没有可变成员的类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
    }
  }
}

这样安全吗?我的理由是它应该是:只要usersSomeMutableOperation更改,任何使用users的先前实例的其他线程已经拥有旧版本的句柄,并且不应受到影响。此外,在未安全构建新实例之前,不会对任何GetUsers请求起作用。

我有什么遗漏的吗?我的构造安全吗?

更新:我可能应该使用Agents来执行此操作,但问题仍然存在:上述安全吗?

2 个答案:

答案 0 :(得分:3)

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

val currentUsers = users
other ? Process(users) recoverWith { case _ => backup ? Process(currentUsers) }

在第一种情况下,您只需获取值 - 这很好 - 但要求backup从不同的线程发生,因此需要val currentUsers

答案 1 :(得分:1)

对我来说很好看。你似乎不需要代理商。