Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Updating Scala collections thread-safely

Tags:

i was wondering if there is any 'easy' way to update immutable scala collections safely. Consider following code:

class a {    private var x = Map[Int,Int]()     def update(p:(Int,Int)) { x = x + (p) } } 

This code is not thread safe, correct? By that i mean that if we have two threads invoking update method and lets say that x is map containing { 1=>2 } and thread A invokes update((3,4)) and only manages to execute the x + (p) part of the code. Then rescheduling occurs and thread B invokes update((13,37)) and successfully updates the variable x. The thread A continues and finishes.

After all this finishes, value x would equal map containing { 1=>2, 3=>4 }, correct? Instead of desired { 1=>2, 3=>4, 13=>37 }. Is there a simple way to fix that? I hope it's undestandable what I'm asking :)

Btw, i know there are solutions like Akka STM but i would prefer not to use those, unless necessary.

Thanks a lot for any answer!

edit: Also, i would prefer solution without locking. Eeeew :)

like image 683
Arg Avatar asked Jul 29 '11 01:07

Arg


People also ask

How do I make collections thread-safe?

The Collections class of java. util package methods that exclusively work on collections these methods provide various additional operations which involves polymorphic algorithms. This method accepts any collection object and, returns a synchronized (thread-safe) collection backed by the specified collection.

Are immutable collections thread-safe?

One advantage of an immutable collection is that it is automatically thread safe. After you create a collection, you can hand it to multiple threads, and they will all see a consistent view. However, an immutable collection of objects is not the same as a collection of immutable objects.

Is mutable map thread-safe?

To get a thread-safe mutable map, you can mix the SynchronizedMap trait trait into whatever particular map implementation you desire. For example, you can mix SynchronizedMap into HashMap, as shown in the code below.

Is Scala queue thread-safe?

Scala and Java collection classes are generally not thread-safe unless they explicitly say so in their docs.


1 Answers

In your case, as Maurício wrote, your collection is already thread safe because it is immutable. The only problem is reassigning the var, which may not be an atomic operation. For this particular problem, the easiest option is to use of the nice classes in java.util.concurrent.atomic, namely AtomicReference.

import java.util.concurrent.atomic.AtomicReference  class a {   private val x = new AtomicReference(Map[Int,Int]())    def update(p:(Int,Int)) {     while (true) {       val oldMap = x.get // get old value       val newMap = oldMap + p // update       if (x.compareAndSet(oldMap, newMap))         return // exit if update was successful, else repeat     }   } } 
like image 59
Jean-Philippe Pellet Avatar answered Sep 30 '22 19:09

Jean-Philippe Pellet