首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >GPars中的NullPointerException,演员

GPars中的NullPointerException,演员
EN

Stack Overflow用户
提问于 2016-05-07 21:48:20
回答 1查看 94关注 0票数 2

Groovy: 1.8.6

GPars: 0.12或1.2.1

操作系统: Ubuntu 14.04 LTS

代码语言:javascript
复制
@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的范围越来越宽,越来越容易发生这种错误。但当范围有限时,该错误永远不会发生。

我不明白为什么会发生这个错误。

EN

回答 1

Stack Overflow用户

发布于 2016-05-08 03:20:40

从您提供的代码示例中,我不能100%确定您要实现的目标。您似乎正在尝试为提供的范围内的每个值创建一个Actor,并通过打印出提供的值来响应消息。

鉴于此,您的代码存在一些问题。主要问题是缺少loop{}闭包,该闭包确保Actor在处理消息后等待下一个传入消息。

其次,调用stop()也无济于事。它只是阻止Actor接收额外的消息。在您的情况下,它不会伤害任何东西,因为您立即调用join,但增加了混乱。

为了让它正常工作,下面是简化为工作示例的代码:

代码语言:javascript
复制
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中,闭包中的最后一行是return语句。因此,由于闭包中的最后一行是println,因此它的返回值为空。因此,您的Reactor返回null,它被视为发送给Actor的消息,并再次进行处理。

为了避免这种情况,您需要评估返回的消息,并仅委托该消息/或者如果该消息尚未处理,则打印该消息。我已经更新了你的代码,为了清楚起见,我特意返回了'done‘作为返回消息。您可以将代码更改为在处理之前只检查null消息:

导入groovyx.gpars.actor.Actors

代码语言:javascript
复制
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
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37089361

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档