Skip to content

Commit 618d42c

Browse files
authored
Merge pull request scala#5323 from szeiger/issue/7838-2
SI-7838 Document the multi-threading semantics of List and Vector
2 parents f026be2 + a528823 commit 618d42c

File tree

3 files changed

+15
-0
lines changed

3 files changed

+15
-0
lines changed

src/library/scala/collection/immutable/List.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ import java.io.{ObjectOutputStream, ObjectInputStream}
2525
* This class is optimal for last-in-first-out (LIFO), stack-like access patterns. If you need another access
2626
* pattern, for example, random access or FIFO, consider using a collection more suited to this than `List`.
2727
*
28+
* $usesMutableState
29+
*
2830
* ==Performance==
2931
* '''Time:''' `List` has `O(1)` prepend and head/tail access. Most other operations are `O(n)` on the number of elements in the list.
3032
* This includes the index-based lookup of elements, `length`, `append` and `reverse`.

src/library/scala/collection/immutable/Traversable.scala

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,17 @@ import mutable.Builder
1818
/** A trait for traversable collections that are guaranteed immutable.
1919
* $traversableInfo
2020
* @define mutability immutable
21+
*
22+
* @define usesMutableState
23+
*
24+
* Note: Despite being an immutable collection, the implementation uses mutable state internally during
25+
* construction. These state changes are invisible in single-threaded code but can lead to race conditions
26+
* in some multi-threaded scenarios. The state of a new collection instance may not have been "published"
27+
* (in the sense of the Java Memory Model specification), so that an unsynchronized non-volatile read from
28+
* another thread may observe the object in an invalid state (see
29+
* [[https://issues.scala-lang.org/browse/SI-7838 SI-7838]] for details). Note that such a read is not
30+
* guaranteed to ''ever'' see the written object at all, and should therefore not be used, regardless
31+
* of this issue. The easiest workaround is to exchange values between threads through a volatile var.
2132
*/
2233
trait Traversable[+A] extends scala.collection.Traversable[A]
2334
// with GenTraversable[A]

src/library/scala/collection/immutable/Vector.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ object Vector extends IndexedSeqFactory[Vector] {
4040
* endian bit-mapped vector trie with a branching factor of 32. Locality is very good, but not
4141
* contiguous, which is good for very large sequences.
4242
*
43+
* $usesMutableState
44+
*
4345
* @see [[http://docs.scala-lang.org/overviews/collections/concrete-immutable-collection-classes.html#vectors "Scala's Collection Library overview"]]
4446
* section on `Vectors` for more information.
4547
*

0 commit comments

Comments
 (0)