あなたが提供したコード例から、あなたが達成しようとしていることは 100% わかりません。Actor
提供された範囲内の各値を試行し、提供された値を出力してメッセージに反応しようとしているようです。
それを考えると、あなたのコードにはいくつかの問題があります。主な問題は、loop{}
クロージャーがないことです。これにより、Actor
メッセージを処理した後、次の受信メッセージを確実に待機できます。
第二に、呼び出しstop()
も役に立ちません。Actor
が追加のメッセージを受信しないようにするだけです。すぐに join を呼び出すので、あなたの場合は何も害はありませんが、混乱を招きます。
これを機能させるために、コードを単純化して実際の例にします。
import groovyx.gpars.actor.Actors
def a = 1
def b = 100000
def actor = Actors.actor {
loop {
react {
println it
}
}
}
(a..b).each {
actor << it
}
actor.join()
この例では、範囲内の各値に対してメッセージがアクターに追加されます。アクターは値を出力することでメッセージに反応し、「ループ」クロージャーのために次の受信メッセージを待ちます。
したがって、その例はあなたが望むものを達成するはずです。ただし、コードで何が起こっているかを明確にするために、ここに説明があります。
がメッセージに「反応」するときActor
、メッセージは に送信されますReactor
。値を明示的に返さなくても、Groovy では Closure 内の最後の行が return ステートメントです。その結果、クロージャー内の最後の行は であるためprintln
、その戻り値は null です。そのため、Reactor
null が返されます。これは へのメッセージとして扱われ、Actor
再度処理されます。
このシナリオを回避するには、返信メッセージを評価し、メッセージのみを委任するか、まだ処理されていない場合はメッセージを出力する必要があります。コードを更新しました。明確にするために、戻りメッセージとして意図的に「完了」を返します。null
メッセージを処理する前にチェックするようにコードを変更できます。
groovyx.gpars.actor.Actors のインポート
def a = 1
def b = 100000
def reactor2 = Actors.reactor { message ->
if(!message.equals("done")) {
println "\t\tReact Again: $message"
}
return "done"
}
def reactor = Actors.reactor { message ->
if(!message.equals("done")) {
println "\tReact: $message"
reactor2 << message
}
return "done"
}
def actor = Actors.actor {
loop {
react {
if(!it.equals("done")) {
println it
reactor << it
}
}
}
}
(a..b).each {
actor << it
// actor.oi
}
actor.join()