【问题标题】:How to use ConcurrentLinkedQueue in Scala?如何在 Scala 中使用 ConcurrentLinkedQueue?
【发布时间】:2015-01-24 18:27:08
【问题描述】:
val nodes = Array.fill[mutable.Buffer[Int]](numNodes){new ArrayBuffer[Int]() with mutable.SynchronizedBuffer[Int]}

def addMutualEdge(i: Int)(j: Int) {nodes(i) += j; nodes(j) += i}

当我编译这个时,我得到了弃用警告:

SynchronizedBuffer is deprecated. Synchronization via traits is deprecated as it is inherently reliable. Consider java.util.concurrent.ConcurrentLinkedQueue as an alternative

如何在上面的代码中使用java库?

【问题讨论】:

    标签: scala scala-2.11


    【解决方案1】:

    您可以只使用ConcurrentLinkedQueue 而不是Buffer,因为它也是可变的:

    scala> import java.util.concurrent._
    import java.util.concurrent._
    
    scala> val nodes = Array.fill(10){new ConcurrentLinkedQueue[Int]()}
    nodes: Array[java.util.concurrent.ConcurrentLinkedQueue[Int]] = Array([], [], [], [], [], [], [], [], [], [])
    
    scala> def addMutualEdge(i: Int)(j: Int) {nodes(i).add(j); nodes(j).add(i)}
    addMutualEdge: (i: Int)(j: Int)Unit
    

    这是最快的选择,因为此队列基于 CAS 操作,因此没有阻塞(与 SynchronizedBuffer 相比)。另一种选择是直接同步操作:

    scala> val nodes = Array.fill[mutable.Buffer[Int]](10){new ArrayBuffer[Int]()}
    nodes: Array[scala.collection.mutable.Buffer[Int]] = Array(ArrayBuffer(), ArrayBuffer(), ArrayBuffer(), ArrayBuffer(), ArrayBuffer(), ArrayBuffer(), ArrayBuffer(), ArrayBuffer(), ArrayBuffer(), ArrayBuffer())
    
    scala> def addMutualEdge(i: Int)(j: Int) = this.synchronized{nodes(i) += j; nodes(j) += i}
    addMutualEdge: (i: Int)(j: Int)scala.collection.mutable.Buffer[Int]
    

    你也可以将java的Collections.synchronizedList(...)scala.collection.JavaConverters.asScala结合使用

    import java.util._
    import scala.collection.JavaConverters._
    scala> val nodes = Array.fill(10){Collections.synchronizedList(new ArrayBuffer[Int]().asJava).asScala}
    nodes: Array[scala.collection.mutable.Buffer[Int]] = Array(Buffer(), Buffer(), Buffer(), Buffer(), Buffer(), Buffer(), Buffer(), Buffer(), Buffer(), Buffer())
    

    或者你可以使用AtomicReferenceArray:

    implicit class RichAtomic[T](a: AtomicReferenceArray[List[T]]) { def apply(i: Int) = (a,i); def update(i: Int, e: List[T]) = a.set(i, e)}
    implicit class RichList[T](a: (AtomicReferenceArray[List[T]], Int)) { def ::=(e: T) = while({val lst = a._1.get(a._2);!a._1.compareAndSet(a._2, lst, e :: lst)}){}}
    implicit def toList[T](a: (AtomicReferenceArray[List[T]], Int)) = a._1.get(a._2)
    
    val nodes = new AtomicReferenceArray(Array.fill[List[Int]](10){Nil})
    
    scala> def addMutualEdge(i: Int)(j: Int) = {nodes(i) ::= j; nodes(j) ::= i}
    addMutualEdge: (i: Int)(j: Int)Unit
    

    隐式用于提供与Array 类似的接口。请注意,::= 将元素添加到列表的开头。

    【讨论】:

    • 谢谢。如何将 Array 元素 (ConcurrentLinkedQueue) 转换为 Array.. toArray() 返回 Array[AnyRef]。如何返回 Array[Int]
    • 改用.asScala.toArray(导入scala.collection.JavaConverters._
    猜你喜欢
    • 2010-10-11
    • 1970-01-01
    • 2023-03-09
    • 2010-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-11
    • 2011-09-28
    相关资源
    最近更新 更多