2

时髦的:1.8.6

GPars: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的范围越来越宽,这个错误也越来越容易出现。但是当范围有限时,永远不会发生错误。

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

4

1 回答 1

0

从您提供的代码示例中,我不能 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 中,闭包中的最后一行是 return 语句。结果,由于您在 Closure 中的最后一行是 a println,因此返回的是 null。因此,您Reactor返回 null,它被视为发送给 theActor并再次处理的消息。

为避免这种情况,您需要评估返回消息并仅委托消息/或在尚未处理时打印它。我已经更新了您的代码,为了清楚起见,故意返回“完成”作为返回消息。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()
于 2016-05-07T19:20:39.763 回答