1

So, I have a portion of code that looks like the following.

for(a <- 0 until segments)
{
    // do something with elements at index a
}

What is the simplest type of multithreading, that can allow me to execute each element of that loop in a separate thread. I also have global collections (indexed by a) that need to be accessed by each thread. All I see on the internet are futures and actors, but they are quite difficult to grasp. I want something as simple as OpenMP.

I tried the following, but it gave me the error, ';' expected but '.' found. }} thread.start.

for (a <- 0 until segments) {
    val thread = new Thread {
        override def run {
            // do something with elements at index a
        }} thread.start
}
7
  • 1
    docs.scala-lang.org/overviews/core/futures.html Commented Jun 18, 2016 at 16:24
  • Not sure what you really want, but Future.traverse. Commented Jun 18, 2016 at 16:25
  • 1
    Maybe parallel collections would suit you? It won't execute each element on separate thread but it will split the work reasonably to use all your cores. Commented Jun 18, 2016 at 16:27
  • I don't want to go for parallel collections, as that would require me to change a lot of code. Commented Jun 18, 2016 at 16:28
  • do you mean "simplest" as in "shortest" or as in "low level"? Commented Jun 18, 2016 at 16:36

2 Answers 2

5

I asumed you are executing the code just for side effects.

Following code works. You get an error because thread.start should be in a separate line.

for (a <- 0 until 10) {
    val thread = new Thread {
        override def run(): Unit = { 
            // code
        }
    }
    thread.start()
}

you can replace it using futures, to use a thread pool which is much better than spawning possibly a large number of threads.

for (a <- 0 until 10) {
    Future {
        // code
    }
}

however in either case you won't be able to wait till it completes. You can traverse the range and get back the Future that will contains list of all partial results from each of the Futures you start using the second function.

val result: Future[List[Unit]] = Future.traverse((0 until 10).toList)(index => Future {
    // code
})

Having a Future result you can await on it, i.e. block calling thread until all computations are finished.

import scala.concurrent.duration._
import scala.concurrent.Await
Await.ready(result, 1.hour)

Use Await.result to get the result, Await.ready just waits till future is completed.

To wait for threads you would need to build a list when starting them and then call join on each.

I don't think you would need to change existing code to use parallel collections but maybe I don't know something specific to your code. Following code will split the range into chunks that will be processed in parallel.

for (a <- (0 until 10).par) {
   // code
}

With parallel collections you don't need to wait, thread will be blocked until everything is processed.

Sign up to request clarification or add additional context in comments.

4 Comments

What do you mean won't be able to wait. What code do I need to add to wait then?
I edited my answer. If you won't wait, you will not know when your computations are done. Btw there is a great course on parallel programming in scala that I just finished today :p coursera.org/learn/parprog1
@Łukasz you should use Future.successful {} in example
I believe this is definitely something I shouldn't do as the OP wants to execute in multiple threads.
1

You are wrong about parallel collections: they won't require you to change any code beyond what you actually want to change:

 (0 until segments).par.foreach { a =>
    // code
 }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.