1

我的应用程序有一个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更改时已经拥有旧版本的句柄,并且不应该受到影响。此外,在未安全构建新实例之前,不会对任何请求进行操作。SomeMutableOperationusersGetUsers

有什么我想念的吗?我的构造安全吗?

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

4

2 回答 2

3

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

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

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

于 2013-05-11T13:55:43.523 回答
1

在我看来很好。你这里似乎不需要特工。

于 2013-05-11T07:37:03.213 回答