Mutable values in an object

2019-07-05 00:36发布

问题:

In Scala, if I'm planning on having a mutable attribute (e.g. a bag of numbers) of an object, when is it appropriate to

  1. Create a var and use an immutable data structure?
  2. Create a val and use a mutable data structure?

I'm going to throw a guess out that you'd want to use #2 for threaded applications? Are some of the collections thread-safe?

How about in general? (Or does it not really matter?)

回答1:

Between your choices 1 and 2, it doesn't matter - mutable is mutable, and if you read or modify the value from multiple threads, you'll need to synchronize access to the property, no matter if the property itself is a var of an immutable data structure or a val of a mutable data structure. Neither choice will give you automatic synchronization.



回答2:

Not a full answer to your question, but…

Either 1 or 2 in your question would not be fit for a multi-threaded environment — vals with immutable data structures are. For multi-threaded access to mutable collections, I'd still recommend Java's collections from the java.util.concurrent package. E.g., to create a mutable, concurrent hash map:

def emptyConcurrentHashMap[K, V] = {
  import collection.JavaConverters._
  new java.util.concurrent.ConcurrentHashMap[K, V].asScala
}

You still get the more idiomatic Scala accessors like this, and you'd use the special atomic mutator methods (like def putIfAbsent(k: A, v: B): Option[B] and def replace(k: A, oldvalue: B, newvalue: B): Boolean).

Alternatively, you could use an AtomicReference that holds an immutable collection, and replace it with its compareAndSet method.