blue-sky
blue-sky

Reputation: 53786

How to parallelise collections and prevent race condition

I have List of users and I'm comparing each user to every other user by totaling their values. This works fine but when I try to parallelise I get multiple race conditions as the variable totalVar is accessed by multiple threads at same time.

Can I have some pointers on how to parallelise the addition of the values for each list ?

import scala.collection.JavaConversions._
import collection.JavaConverters._

object Question {

  case class User(id: String, value : BigInt) 

  var userList : java.util.List[User] = new java.util.ArrayList[User] 

  def main(args: Array[String]) {

      userList.add(new User("1" , 1))
      userList.add(new User("2" , 1))
      userList.add(new User("3" , 1))
      userList.add(new User("4" , 1))

      //Compare each user to every other user by totaling their
      //values
          var totalValue : BigInt = 0

      for(u <- userList.par){
        for(u1 <- userList.par){
           totalValue = totalValue + u1.value
           println("Adding "+u1.id+","+u1.value+ ","+totalValue)
        }
        println("Total is "+totalValue)
        totalValue = 0
      }

    }

}

Update :

I know this may seem like a pointless example but I'm facing a much more complicated problem and here I'm trying to ask the simplest question which will guide me in the direction of actual problem I am trying to resolve.

Upvotes: 1

Views: 265

Answers (2)

Garrett Hall
Garrett Hall

Reputation: 30022

Try using an AtomicInt which is synchronized:

  val totalValue : new AtomicInt()

  for(u <- userList.par){
    for(u1 <- userList.par){
       totalValue.incrementAndGet(u1.value)
    }
  }

Upvotes: 0

om-nom-nom
om-nom-nom

Reputation: 62835

It is likely that you would not gain much by having two parallel collections (summing two integers is quite lightweight task and scheduling it over and over is not a good idea), it is easier to do with just one:

val total = 
  for(u <- userList.par) yield {
    var partialTotal = 0
    for(u1 <- userList){
      partialTotal += u1.value
      println("Adding "+u1.id+","+u1.value+ ","+totalValue)
    }
    partialTotal
  }.sum

Upvotes: 1

Related Questions