Reputation: 21605
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
}
Upvotes: 1
Views: 4116
Reputation: 8663
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.
Upvotes: 5
Reputation: 40500
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
}
Upvotes: 1