Question

As a newbie of scala and scalaz, when using promise, got a problem. My code like this.

import scalaz._
import Scalaz._

object Main2 extends Application {
  def sleeper() = {
    Thread.sleep(2000)
  }
  val message = promise {
    println("begin")
    sleeper
    println("ok")
    "ok"
  }
  Thread.sleep(5000)
  println("try to get")
  println(message())
}

This output following, which looks strange. It seems that the sleeper method has not been called, and the thread blocked. -

begin
try to get

But if I replace the sleeper calling to a inline sleep, it looks fine -

object Main2 extends Application {
  def sleeper() = {
    Thread.sleep(2000)
  }
  val message = promise {
    println("begin")
    Thread.sleep(2000)
    println("ok")
    "ok"
  }
  Thread.sleep(5000)
  println("try to get")
  println(message())
}

output here -

begin
ok
try to get
ok

I don't understand why, can you gurus please advise?

Was it helpful?

Solution

I cannot give you a complete explanation, but the problem seems to be connected to some issues with the Application trait.

In short: The constructor body of Application is run too early and in a static initialisation context. At that point, it does not handle threads very well (if at all). The current Apidoc says:

Threaded code that references the object will block until static initialization is complete. However, because the entire execution of an object extending Application takes place during static initialization, concurrent code will always deadlock if it must synchronize with the enclosing object.

Starting from Scala 2.9, there is the new App trait which resolves most of these issues, so all you need to do is write object Main2 extends App and it should work.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top