java cost - What object do I synchronize on in Scala?





not method (4)


If the premise is that you want to avoid locking on this because another thread with third party code can lock on the same object, then Scala offers one more level of visibility private[this].

class C {
  private[this] val lock = new Object()
  def method1(): Unit = lock.synchronized {
    println("method1")
  }
}

Here actually no other object other than a particular instance of C can access lock. Even other instances from the same class cannot access lock.

In C# it's pretty straightforward:

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

And I definitely should not make a synchronization on this because it might lead to a deadlock. Likewise, in Scala I saw examples and couldn't get the idea of what is the basic principle of synchronization and object (field) I should use to make a synchronization:

#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...

Would you mind making it clear for me?




  1. Having a lock on object in Scala is the same as having the lock on static field/class in Java, which is basically one of 'hardest' locks. It will block operations not on instance of class, but on class itself in scope of class loader. You should think carefully when introducing locks like this. It doesn't protect you from a deadlock due to incorrect ordering of acquired locks, but instead leads to blocking threads if ones are working with different instances of a class, and may not interfere at all.

  2. having a lock on 'this' or some class (not object) field (mutex) is more relaxed way of synchronization, you should use it for managing access not to class - but to particular instance of this class.

  3. look at actors in akka, they rock and eliminate many of problems with synchronization.

side-note: making synchronization on 'this' doesn't imply deadlocks.




In Scala it's even more straightforward to get the same behavior (I'm assuming you want to lock on the contained object for some reason e.g. more fine-grained control than locking the whole instance of that class):

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

But you should rarely control things this way. In particular, it won't prevent deadlocks in either C# or Scala without a lot of attention to what goes into ....

You should at least use the concurrency tools in java.util.concurrent, and you may want to look into futures or actors.




synchronized is a keyword in Java which is used to make happens before relationship in multithreading environment to avoid memory inconsistency and thread interference error.





java multithreading scala