Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is Scala's collection.mutable.PriorityQueue thread safe?

I am using a PriorityQueue across multiple threads. I am not sure it's a thread safe data-structure.

Is it safe to use scala.collection.mutable.PriorityQueue across multiple threads?

like image 374
Lahiru Avatar asked Aug 06 '15 05:08

Lahiru


People also ask

Is PriorityQueue thread-safe?

Since PriorityQueue is not thread-safe, java provides PriorityBlockingQueue class that implements the BlockingQueue interface to use in a java multithreading environment.

Are mutable objects thread-safe?

A MessageService object is effectively immutable since its state can't change after its construction. So, it's thread-safe. Moreover, if MessageService were actually mutable, but multiple threads only have read-only access to it, it's thread-safe as well.

Is Scala mutable HashMap thread-safe?

The HashMap in the Scala standard library is not thread-safe. This means that if multiple fibers are accessing the same key, and trying to modify the value, this can lead to inconsistent results.

Is Scala list thread-safe?

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.


1 Answers

TL;DR: It is not safe.

Let's have a look! scala.collection.mutable.PriorityQueue uses

private val resarr = new ResizableArrayAccess[A]

where ResizableArrayAccess is defined inside PriorityQueue as

private class ResizableArrayAccess[A] extends AbstractSeq[A] with ResizableArray[A] with Serializable {

From there, going to scala.collection.mutable.ResizableArray, it is obvious that this is not thread safe, e.g. by looking at the update method:

protected var array: Array[AnyRef] = new Array[AnyRef](math.max(initialSize, 1))
 // ... snip ... //
def update(idx: Int, elem: A) {
  if (idx >= size0) throw new IndexOutOfBoundsException(idx.toString)
  array(idx) = elem.asInstanceOf[AnyRef]
}

So we have unprotected access to a mutable var and usage of scala.collection.mutable.PriorityQueue from multiple Threads is not encouraged.

If you really need to use it from multiple threads and concurrency is not important you can use some meaning of synchronization, e.g. scala.util.SyncVar to protect against concurrency issues like race conditions. Otherwise using another data structure is better.

like image 151
Markus1189 Avatar answered Oct 09 '22 10:10

Markus1189