How to make atomic exchange -- Scala way? How to make atomic exchange -- Scala way? multithreading multithreading

How to make atomic exchange -- Scala way?


Scala approach is to favor immutability whenever it is possible (and it's very often possible). Then you do not need anymore copy constructors, locks, mutex, etc.

For example, you can convert the iterator to a List at object construction. Since lists are immutable, you can safely share them without having to lock:

class IteratorWrapper[A]( iter: Iterator[A] ) {  val list = iter.toList  def iteratorCopy = list.iterator}

Here, the IteratorWrapper is also immutable. You can safely pass it around. But if you really need to change the wrapped iterator, you will need more demanding approaches. For instance you could:

  1. Use locks
  2. Transform the wrapper into an Actor
  3. Use STM (akka or other implementations).

Clarifications: I lack information on your problem constraints. But here is how I understand it.

Several threads must traverse simultaneously an Iterator. A possible approach is to copy it before passing the reference to the threads. However, Scala practice aims at sharing immutable objects that do not need to be copied.

With the copy strategy, you would write something like:

//A single iterator producerclass Producer {  val iterator: Iterator[Foo] = produceIterator(...)}//Several consumers, living on different threadsclass Consumer( p: Producer ) {  def consumeIterator = {    val iteratorCopy = copy( p.iterator ) //BROKEN !!!    while( iteratorCopy.hasNext ) {      doSomething( iteratorCopy.next )    }   }  }

However, it is difficult (or slow) to implement a copy method which is thread-safe. A possible solution using immutability will be:

class Producer {  val lst: List[Foo] = produceIterator(...).toList   def iteratorCopy = list.iterator}class Consumer( p: Producer ) {  def consumeIterator = {    val iteratorCopy = p.iteratorCopy     while( iteratorCopy.hasNext ) {      doSomething( iteratorCopy.next )    }   }  }

The producer will call produceIterator once at construction. It it immutable because its state is only a list which is also immutable. The iteratorCopy is also thread-safe, because the list is not modified when creating the copy (so several thread can traverse it simultaneously without having to lock).

Note that calling list.iterator does not traverse the list. So it will not decrease performances in any way (as opposed to really copying the iterator each time).