2016-05-07 17 views
2

なGroovy:1.8.6NullPointerExceptionが、俳優

GPars:0.12または1.2.1

OS:このコードが実行されるのUbuntu 14.04 LTS

@Grab(group='org.codehaus.gpars', module='gpars', version='0.12') 
import groovyx.gpars.actor.Actor 


import groovyx.gpars.actor.Actors 


def a = 1 
def b = 100000 

def reactor2 = Actors.reactor { 
    println " $it" 
} 

def reactor1 = Actors.reactor { 
    println "$it" 
    reactor2 << it 
} 

Actor actor = Actors.actor { 
    (a..b).each {reactor1 << it} 
} 

actor.join() 

reactor1.stop() 
reactor1.join() 

reactor2.stop() 
reactor2.join() 

、NullPointerExceptionが頻繁に発生しています。 aとbの範囲が広くて幅が広いほど、このエラーはより簡単に発生します。しかし、範囲が限定されている場合、エラーは発生しません。

エラーが発生した理由を理解できません。

+0

あなたがあなたの質問に例外を入れることはできますか? –

+0

また、3歳未満のGroovyのバージョンを使用できますか? –

答えて

0

あなたが提供したコード例から、私はあなたが達成しようとしていることを100%確信していません。指定された範囲内の各値に対してActorを試しているようで、提示された値を印刷してメッセージに反応します。

あなたのコードにはいくつか問題があります。主な問題は、クロージャがないことです。これは、Actorが処理した後に次の着信メッセージを待つことを保証します。

第2に、stop()を呼び出すことも役に立ちません。 Actorが追加のメッセージを受信しなくなります。あなたがすぐに参加を呼び出すので、あなたの場合は何も傷つけることはありませんが、混乱を招きます。

この作業を取得するには、ここでの実施例に簡略化され、あなたのコードは次のとおりです。この例では

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

、範囲内の各値に対して、メッセージは、メッセージに反応する俳優に追加されますその値を印字することで、 'loop'クロージャが次の着信メッセージを待つためです。

この例では、目的を達成する必要があります。しかし、あなたのコードで何が起こっているかを明確にするために、ここでは説明します。

Actorがメッセージに反応すると、Reactorにメッセージが送信されます。明示的に値を返さなくても、GroovyではClosure内の最後の行がreturn文になります。その結果、クロージャ内の最後の行がprintlnであるため、その戻り値はnullです。したがって、Reactorはnullを返します。これはActorへのメッセージとして扱われ、再び処理されます。

このシナリオを回避するには、返信メッセージを評価し、メッセージを委任するか、まだ処理されていない場合にのみ印刷する必要があります。あなたのコードを更新し、明確にするために返信メッセージとして意図的に 'done'を返します。あなたはそれを処理する前に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() 
+0

このソリューションは効果がありましたか? – pczeus