вызывающая функция при использовании обещания скалаза - PullRequest
3 голосов
/ 11 января 2012

У новичка в scala и scalaz при использовании обещания возникла проблема. Мой код такой.

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())
}

Этот вывод следующий, что выглядит странно. Кажется, что спящий метод не был вызван, а поток заблокирован. -

begin
try to get

Но если я заменю спящего, вызывающего встроенный сон, он выглядит хорошо -

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())
}

вывод здесь -

begin
ok
try to get
ok

Я не понимаю, почему, гуру, пожалуйста, посоветуйте?

1 Ответ

8 голосов
/ 11 января 2012

Я не могу дать вам полное объяснение, но проблема, похоже, связана с некоторыми проблемами с чертой Application.

Вкратце: тело конструктора Application запускается слишком рано и находится встатический контекст инициализации.В этот момент он не очень хорошо обрабатывает потоки (если вообще). текущий Apidoc говорит:

Потоковый код, который ссылается на объект, будет блокироваться до завершения статической инициализации.Однако, поскольку все выполнение приложения, расширяющего объект, происходит во время статической инициализации, параллельный код всегда блокируется, если он должен синхронизироваться с включающим объектом.

Начиная с Scala 2.9 есть новая черта App, которая решает большинство из этих проблем, поэтому все, что вам нужно сделать, это написать object Main2 extends App, и она должна работать.

...