8

I am new to this Scala world and I am trying some exercises from a book. So, I have an example that print a vector in sequential and parallel fashion. The former works perfectly and the later hangs the console.

Code

val v = Vector.range(0, 10)
v.foreach(println)

Code output

0123456789

But if I use the same code, but instead of using foearch, use par, it freezes the console

val v = Vector.range(0,10)
v.par.foreach(println)

The book I am using says that the output should be something like:

5678901234    

But it hangs and the program never finishes.

Can someone explain me why?

CroMagnon
  • 1,218
  • 7
  • 20
  • 32
Israel Zinc
  • 2,713
  • 2
  • 18
  • 30
  • 4
    It's not obvious, but it's due to starting threads from a static initializer. There's an SO for it, I'll try to find it. https://issues.scala-lang.org/browse/SI-8119 and http://stackoverflow.com/questions/15176199/scala-parallel-collection-in-object-initializer-causes-a-program-to-hang The ticket suggests workarounds. Easiest is to make it local, `{ x.par }`. – som-snytt Feb 10 '17 at 06:25
  • 2
    I tested with scala 2.12.1 - and console hanged. With scala 2.11.8 works fine. – Andrzej Jozwik Feb 10 '17 at 07:31
  • Thanks for the answers guys, I was just curious about the reason. I'm not using it in a current project. – Israel Zinc Feb 13 '17 at 01:32
  • I got this to work by starting the repl with `scala -Yrepl-class-based` (per [this comment](https://issues.scala-lang.org/browse/SI-8119?focusedCommentId=67218&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-67218)), but everything else I tried (including wrapping various parts of the command in braces) did not work. – turtlemonvh Jan 03 '19 at 21:00
  • Further evidence: this works in the default repl: `class X { Vector.range(0,10). par.foreach(print) } ; new X`, but this doesn't `object X { Vector.range(0,10). par.foreach(print) } ; X`. – turtlemonvh Jan 03 '19 at 21:15
  • Here is another one that doesn't work: `import scala.concurrent.forkjoin.ForkJoinPool; import scala.collection.parallel.ForkJoinTaskSupport; var v = Vector.range(0,10).par; v.tasksupport = new ForkJoinTaskSupport(new ForkJoinPool(4)); v.foreach(print)`. I thought maybe creating the pool explicitly would help, but it seems to still be lazily evaluated, and I still get a deadlock. – turtlemonvh Jan 03 '19 at 21:21

1 Answers1

1

It is better to post whole the program wich is hanged.

I've just tested it with scala 2.12.8 and jvm 1.8.0_161:

object MainClassss {
  def main(args: Array[String]): Unit = {
    val v = Vector.range(0,10)
    (0 to 999999).foreach(_ => v.par.foreach(println))
  }
}

the program has executed well with output and hasn't hanged.

If your program reproduced the aforementioned issue you need to take a thread dump by:

$ jstack <PID>

where PID is the process id.

Or you can take by jvisualvm jvm tool.

You can analyze why your program is hanged owing to caught thread dump if the program has some code blocking it from execution.

Matthew I.
  • 1,793
  • 2
  • 10
  • 21