[英]NullPointerException in GPars, Actor
Groovy:1.8.6
GPar:0.12或1.2.1
操作系統: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的范圍越來越寬,此錯誤越來越容易發生。 但是,如果范圍有限,則永遠不會發生該錯誤。
我不明白為什么會發生錯誤。
從您提供的代碼示例中,我不確定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.Actor
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()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.