3

I would like to know whether an immutable scala collection (e.g. immutable.HashMap) is thread-safe or not. The content may obviously not change, but mutable state of internals for optimization is unclear to me.

Keys and values are assumed to be immutable

Thanks for your help

5
  • 1
    What is "mutable state of internals"?
    – Nikita
    Commented Jan 30, 2017 at 11:26
  • Obviously if you are going to manipulate the objects that are kept by immutable collection it is not going to be thread safe. Those objects should be immutable as well.
    – Atais
    Commented Jan 30, 2017 at 11:27
  • If we assume keys and values are immutable
    – ogen
    Commented Jan 30, 2017 at 11:29
  • @ipoteka Do not know, some rearrangement of data
    – ogen
    Commented Jan 30, 2017 at 11:29
  • Yes, they are thread safe.
    – pedrofurla
    Commented Jan 30, 2017 at 12:02

2 Answers 2

10

No, they're not.

Even though collections are immutable they may have some internal mutable state. For instance documentation for Vector and List explicitly states it

Note: Despite being an immutable collection, the implementation uses mutable state internally during construction. These state changes are invisible in single-threaded code but can lead to race conditions in some multi-threaded scenarios. The state of a new collection instance may not have been "published" (in the sense of the Java Memory Model specification), so that an unsynchronized non-volatile read from another thread may observe the object in an invalid state (see SI-7838 for details). Note that such a read is not guaranteed to ever see the written object at all, and should therefore not be used, regardless of this issue. The easiest workaround is to exchange values between threads through a volatile var.

2
  • Note the "during construction" note. Once constructed immutable collections are thread safe. Before that, they don't exist.
    – Dima
    Commented Mar 29, 2019 at 11:41
  • 1
    Note that "the implementation [...] can lead to race conditions in some multi-threaded scenarios" and "an unsynchronized non-volatile read from another thread may observe the object in an invalid state". In other words, it is not always thread safe.
    – Tim
    Commented Mar 29, 2019 at 13:58
1

They are.

New collection is created with each update. To avoid unnecessary copies, structural sharing is used, therefore you always can refer to some version of collection, and that particular version is thread-safe.

5
  • 1
    Thanks for your help. Is there any official documentation about this ? The Java HashMap doc explicitly says that the get is Thread safe whn no update is made to the collection.
    – ogen
    Commented Jan 30, 2017 at 13:19
  • 2
    @ogen You can't make updates to an immutable collection. Immutability automatically gives you thread safety.
    – puhlen
    Commented Jan 30, 2017 at 14:18
  • 4
    @puhlen This is not correct, immutability does not guarantee thread safety, it just means that no mutable state is exposed in the interface. An immutable data structure may contain mutable data for internal use and may therefore not be thread safe.
    – Tim
    Commented Nov 5, 2018 at 18:53
  • @Tim if mutable state is not exposed, that means that it cannot be mutated (you can't mutate something you can't access), which makes it ... immutable.
    – Dima
    Commented Mar 29, 2019 at 11:40
  • 1
    @Dima This is not correct. A method on an immutable object can mutate internal state. That state can then be used to optimised future function invocations. E.g. a lazy val or memoization. The interface remains immutable because it does not allow changes to the externally-visible state.
    – Tim
    Commented Mar 29, 2019 at 11:55

Not the answer you're looking for? Browse other questions tagged or ask your own question.