Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use ConcurrentLinkedQueue in Scala?

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}

When I compile this, I get deprecation warning:

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

How to use java library in the above code?

like image 411
Anish Shah Avatar asked Jan 24 '15 18:01

Anish Shah


People also ask

How does ConcurrentLinkedQueue work?

A ConcurrentLinkedQueue is an unbounded, thread-safe, and non-blocking queue. Unlike a LinkedBlockingQueue, a ConcurrentLinkedQueue is a non-blocking queue. Thus, it does not block a thread once the queue is empty. Instead, it returns null.

How do you iterate ConcurrentLinkedQueue?

The iterator() method of ConcurrentLinkedQueue is used to returns an iterator of the same elements as this ConcurrentLinkedQueue in a proper sequence. The elements returned from this method contains elements in order from first(head) to last(tail). The returned iterator is weakly consistent.

Why use ConcurrentLinkedQueue?

A ConcurrentLinkedQueue is an appropriate choice when many threads will share access to a common collection. Like most other concurrent collection implementations, this class does not permit the use of null elements.

What is ConcurrentLinkedQueue?

ConcurrentLinkedQueue is an unbounded thread-safe queue which arranges the element in FIFO. New elements are added at the tail of this queue and the elements are added from the head of this queue. ConcurrentLinkedQueue class and its iterator implements all the optional methods of the Queue and Iterator interfaces.


1 Answers

You may just use ConcurrentLinkedQueue instead of Buffer as it's also mutable:

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

It's fastest option as this queue is based on CAS-operations, so no blocking there (in comparision with SynchronizedBuffer). Another option is to synchronize operations directly:

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]

You can also use java's Collections.synchronizedList(...) in combination with 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())

Or you can use 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

Implicits used to provide simillar interface as for just Array. Note, that ::= adds element to the start of list.

like image 182
dk14 Avatar answered Oct 13 '22 21:10

dk14