3

Scalaとscalazの初心者として、promiseを使用すると、問題が発生しました。このような私のコード。

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

この出力は次のとおりですが、奇妙に見えます。sleeperメソッドが呼び出されておらず、スレッドがブロックされているようです。-

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

理由がわかりませんが、教祖にアドバイスしてもらえますか?

4

1 に答える 1

8

完全な説明はできませんが、問題はApplication形質のいくつかの問題に関連しているようです。

つまり、のコンストラクター本体はApplication、静的な初期化コンテキストで実行されるのが早すぎます。その時点では、スレッドをうまく処理できません(あるとしても)。現在のApidocは次のように述べています。

オブジェクトを参照するスレッドコードは、静的初期化が完了するまでブロックされます。ただし、アプリケーションを拡張するオブジェクトの実行全体は静的初期化中に行われるため、並行コードは、それを囲むオブジェクトと同期する必要がある場合、常にデッドロックになります。

Scala 2.9から、これらの問題のほとんどを解決する新しいApp特性があるので、あなたがする必要があるのは書くことだけでありobject Main2 extends App、それはうまくいくはずです。

于 2012-01-11T10:12:08.340 に答える