如何通过 GPars 中的主角色终止所有从属角色?
How to terminate all slave actors via master actor in GPars?
我想让我的主 actor 在第一个 actor 完成工作后立即终止所有 slave actor。
但是,我不知道如何从我的主人向所有奴隶发送广播。有这方面的功能或编程模式吗?
解决这个问题的另一种方法是给主控一个所有从属的列表并循环遍历它们,向每个从属发送一条消息以终止,但是从属也需要主控作为属性,我认为这是一个问题:
import groovyx.gpars.actor.Actor
import groovyx.gpars.actor.DefaultActor
class Slave extends DefaultActor {
Actor master
int t
void act() {
t = new Random().nextInt(1337)
println "It's me, $t"
master.send 0
}
}
class Master extends DefaultActor {
List slaves
void afterStart() {
println "Master initialized!"
}
void killTheSlaves() {
for (i in 0..slaves.size()-1){
slaves[i].send -1
}
}
void act() {
react { int num ->
if (num == 0)
killTheSlaves()
}
}
}
def sl = new Slave().start()
def ma = new Master(slaves: [sl]).start()
sl.master = ma
此代码无法编译。
错误信息:
An exception occurred in the Actor thread Actor Thread 2
java.lang.NullPointerException: Cannot invoke method send() on null object
at org.codehaus.groovy.runtime.NullObject.invokeMethod(NullObject.java:91)
at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:48)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
at org.codehaus.groovy.runtime.callsite.NullCallSite.call(NullCallSite.java:35)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
at Slave.act(ConsoleScript14:11)
at groovyx.gpars.actor.DefaultActor.handleStart(DefaultActor.java:342)
at groovyx.gpars.actor.AbstractLoopingActor.handleMessage(AbstractLoopingActor.java:70)
at groovyx.gpars.util.AsyncMessagingCore.run(AsyncMessagingCore.java:132)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
创建slave后好像无法设置sl.master
有解决办法吗?
非常感谢任何帮助。
提前致谢!
您应该先设置演员然后再启动他们:
def sl = new Slave()
def ma = new Master(slaves: [sl])
sl.master = ma
sl.start()
ma.start()
但是,您的 Slave actors 在主人试图杀死他们之前通过 运行 自己的 act() 方法完成,因此实际上不需要杀死 slaves。
GPars 为 actor 提供了一个 terminate() 方法来优雅地杀死它们,因此您可以考虑将方法更改为:
void killTheSlaves() {
for (i in 0..slaves.size()-1){
slaves[i].terminate()
}
}
我想让我的主 actor 在第一个 actor 完成工作后立即终止所有 slave actor。
但是,我不知道如何从我的主人向所有奴隶发送广播。有这方面的功能或编程模式吗?
解决这个问题的另一种方法是给主控一个所有从属的列表并循环遍历它们,向每个从属发送一条消息以终止,但是从属也需要主控作为属性,我认为这是一个问题:
import groovyx.gpars.actor.Actor
import groovyx.gpars.actor.DefaultActor
class Slave extends DefaultActor {
Actor master
int t
void act() {
t = new Random().nextInt(1337)
println "It's me, $t"
master.send 0
}
}
class Master extends DefaultActor {
List slaves
void afterStart() {
println "Master initialized!"
}
void killTheSlaves() {
for (i in 0..slaves.size()-1){
slaves[i].send -1
}
}
void act() {
react { int num ->
if (num == 0)
killTheSlaves()
}
}
}
def sl = new Slave().start()
def ma = new Master(slaves: [sl]).start()
sl.master = ma
此代码无法编译。
错误信息:
An exception occurred in the Actor thread Actor Thread 2 java.lang.NullPointerException: Cannot invoke method send() on null object at org.codehaus.groovy.runtime.NullObject.invokeMethod(NullObject.java:91) at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:48) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48) at org.codehaus.groovy.runtime.callsite.NullCallSite.call(NullCallSite.java:35) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125) at Slave.act(ConsoleScript14:11) at groovyx.gpars.actor.DefaultActor.handleStart(DefaultActor.java:342) at groovyx.gpars.actor.AbstractLoopingActor.handleMessage(AbstractLoopingActor.java:70) at groovyx.gpars.util.AsyncMessagingCore.run(AsyncMessagingCore.java:132) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745)
创建slave后好像无法设置sl.master
有解决办法吗?
非常感谢任何帮助。
提前致谢!
您应该先设置演员然后再启动他们:
def sl = new Slave()
def ma = new Master(slaves: [sl])
sl.master = ma
sl.start()
ma.start()
但是,您的 Slave actors 在主人试图杀死他们之前通过 运行 自己的 act() 方法完成,因此实际上不需要杀死 slaves。
GPars 为 actor 提供了一个 terminate() 方法来优雅地杀死它们,因此您可以考虑将方法更改为:
void killTheSlaves() {
for (i in 0..slaves.size()-1){
slaves[i].terminate()
}
}