scala - 如何在 Scala 中使用 ConcurrentLinkedQueue?

标签 scala scala-2.11

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 库?

最佳答案

您可以使用 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 类似的接口(interface)的隐式.请注意,::=将元素添加到列表的开头。

关于scala - 如何在 Scala 中使用 ConcurrentLinkedQueue?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28128786/

相关文章:

scala - 在scala中获取当前文件的文件名

java - 如何停止由 java 中的 ProcessBuilder 启动的进程

sbt - 对 scala.ScalaObject 的错误符号引用

scala - Play Framework : Modules were resolved with conflicting cross-version suffixes

java - 提升 json :Custom serializer for java 8 LocalDateTime throwing mapping exception

tomcat - scalate 不编译 tomcat 中的模板

mysql - MySQL : ClassNotFoundException on driver 的 Slick 2.1 代码生成器

scala - AWS EB部署-我的应用程序在哪里?

带下划线的 Scala 字符串插值

java - 如何使用Node Client连接到elasticsearch中的不同主机