在 Scala 中同步哪个对象?

2022-09-03 09:01:25

在C#中,它非常简单:

class Class1{
  private static readonly object locker = new object();
  void Method1(){
    lock(locker) { .... }
  }
}

而且我绝对不应该进行同步,因为它可能会导致死锁。同样,在Scala中,我看到了一些例子,但无法理解我应该用来进行同步的同步和对象(场)的基本原理是什么:this

#1
def add(user: User) {
  // tokenizeName was measured to be the most expensive operation.
  val tokens = tokenizeName(user.name)

  tokens.foreach { term =>
    userMap.synchronized {
      add(term, user)
    }
  }
}

#2
class Person(var name: String) {
  def set(changedName: String) {
    this.synchronized {
      name = changedName
    }
  }
}

#3 and so on...

你介意为我说清楚吗?


答案 1

在Scala中,获得相同的行为甚至更简单(我假设出于某种原因,您希望锁定包含的对象,例如,比锁定该类的整个实例更精细的控制):

class Class1 {
  private object Locker
  def method1 { Locker.synchronized { ... } }
}

但你很少应该以这种方式控制事情。特别是,它不会防止C#或Scala中的死锁,而无需大量关注。...

您至少应该使用 中的并发工具,并且您可能希望查看未来或参与者。java.util.concurrent


答案 2
  1. 在Scala中对对象进行锁定与在Java中对静态字段/类进行锁定是一样的,这基本上是“最难”的锁定之一。它将阻止操作,而不是在类的实例上,而是在类装入器的作用域中阻止类本身的操作。在引入这样的锁时,您应该仔细考虑。它不会保护您免受由于获取的锁的顺序不正确而导致的死锁,而是在使用类的不同实例时导致阻塞线程,并且可能根本不会干扰。

  2. 在“this”或某个类(不是对象)字段(互斥体)上锁定是更轻松的同步方式,您应该使用它来管理对类的访问 - 而是对此类的特定实例的访问。

  3. 看看阿卡的演员,他们摇滚并消除了许多同步问题。

旁注:在“this”上进行同步并不意味着死锁。