Reputation: 53786
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
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
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