簡體   English   中英

GPar中的NullPointerException,Actor

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM