我在多个线程中使用PriorityQueue
。我不确定它是一个线程安全的数据结构。
跨多个线程使用scala.collection.mutable.PriorityQueue
是否安全?
答案 0 :(得分:4)
根据定义,可变对象不是线程安全的,因此我不会将名为 mutable 的包中的任何内容视为线程安全。正如已经指出的那样,java.util.concurrent.PriorityBlockingQueue
可能是一个不错的选择。
如果您想研究Scala集合,scala.collection.immutable.Queue
可能是一个很好的起点。请参阅Concrete Immutable Collection Classes。
答案 1 :(得分:4)
TL; DR:这不安全。
我们来看看吧! scala.collection.mutable.PriorityQueue uses
private val resarr = new ResizableArrayAccess[A]
其中ResizableArrayAccess在PriorityQueue中为defined为
private class ResizableArrayAccess[A] extends AbstractSeq[A] with ResizableArray[A] with Serializable {
从那里开始scala.collection.mutable.ResizableArray
,显然这不是线程安全的,例如通过查看update方法:
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]
}
因此,我们对不可变的var进行了无保护的访问,并且不鼓励使用来自多个线程的scala.collection.mutable.PriorityQueue
。
如果你真的需要在多个线程中使用它并且并发性并不重要,你可以使用某些同步意义,例如: scala.util.SyncVar
以防止竞争条件等并发问题。否则使用其他数据结构会更好。
答案 2 :(得分:1)
Scala和Java集合类通常不是线程安全的,除非他们在他们的文档中明确说明。在这种情况下,我不认为scala.collection.mutable.PriorityQueue
是线程安全的,请尝试使用java.util.concurrent.PriorityBlockingQueue
。