Scala同步最佳实践

时间:2014-04-02 13:59:47

标签: multithreading scala

我开始学习Scala和Akka作为演员模型。例如,在像C这样的命令式语言中,我可以使用几种不同的方法来同步线程,例如二叉树;一个简单的信号量或互斥,原子操作等等。

然而,Scala是一种功能面向对象的语言,它可以利用Akka库(例如)实现一个actor模型。如何在Scala中实现同步?假设我有二进制树,我的程序假设遍历并执行不同的操作。我应该如何确保两个不同的演员不是,例如,同时删除相同的节点?

2 个答案:

答案 0 :(得分:8)

如果要对数据结构进行同步访问,只需使用synchronized AnyRef方法同步块。例如:

object Test {
  private val myMap = collection.mutable.Map.empty[Int, Int]
  def set(key: Int, value: Int): Unit = synchronized { myMap(key) = value }
  def get(key: Int): Option[Int] = synchronized { myMap.get(key) }
}

然而,使用actor的目的是避免线程相互阻塞,这会损害可伸缩性。管理可变状态的Actor方式是将状态设置为Actor实例的私有状态,并且仅响应消息而更新或访问。这是一个更复杂的设计,如:

// define case classes Get, Set, Value here.
class MapHolderActor extends Actor {
  private val myMap = collection.mutable.Map.empty[Int, Int] 
  def receive {
    case Get(key) => sender ! Value(myMap.get(key))
    case Set(key, value) => myMap(key) = value
  }
}

答案 1 :(得分:5)

  1. 在较高的级别上,您可以将Actor用作互斥锁:它会逐个处理所有传入的消息。
  2. 在较低级别(但不是在actor级别),没有什么能阻止你使用普通的旧Java并发原语
  3. 使用@Tanmay提出的不可变数据结构,因此不存在就地修改,因此没有数据竞争
  4. transactors(虽然在最近的akka​​版本中已弃用)