Как завершить работу всех подчиненных акторов через главного актора в GPars?

Я бы хотел, чтобы мой главный актер завершал работу всех подчиненных актеров, как только первый закончит свою работу.
Однако я понятия не имею, как я могу послать широковещательную рассылку от моего хозяина всем подчиненным. Есть ли для этого функция или шаблон программирования?

Другой способ решить эту проблему может заключаться в том, чтобы дать мастеру список всех ведомых устройств и прокрутить их в цикле, посылая каждому сообщение о завершении, однако ведомым устройствам также требуется ведущее устройство в качестве атрибута, и я думаю, что это проблема:

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

Этот код не компилируется.
Сообщение об ошибке:

Возникло исключение в потоке Actor Thread 2 java.lang.NullPointerException: невозможно вызвать метод send () для нулевого объекта в org.codehaus.groovy.runtime.NullObject.invokeMethod (NullObject.java:91) в org.codehaus.groovy .runtime.callsite.PogoMetaClassSite.call (PogoMetaClassSite.java:48) по адресу org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall (CallSiteArray.java:48) по адресу org.codehaus.by (NullCallSite.java:35) на org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall (CallSiteArray.java:48) на org.codehaus.groovy.runtime.callsite.AbstractCallSite.call.javaCallSite.call.java:11Site org.codehaus.groovy.runtime.callsite.AbstractCallSite.call (AbstractCallSite.java:125) в Slave.act (ConsoleScript14: 11) в groovyx.gpars.actor.DefaultActor.handleStart (DefaultActor.java:342) в groovyx.gpars .actor.AbstractLoopingActor $ 1.handleMessage (AbstractLoopingActor.java:70) в gr oovyx.gpars.util.AsyncMessagingCore.run (AsyncMessagingCore.java:132) в java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1142) в java.util.concurol.java:1142 617) на java.lang.Thread.run (Thread.java:745)

Похоже, я не могу установить sl.master после того, как создал подчиненное устройство.

Есть ли обходной путь для этого?

Любая помощь приветствуется.
Заранее спасибо!


person hsvar    schedule 28.11.2016    source источник


Ответы (1)


Вы должны сначала настроить актеров, а затем запустить их: def sl = new Slave() def ma = new Master(slaves: [sl]) sl.master = ma sl.start() ma.start()

Однако ваши подчиненные акторы заканчивают работу сами, исчерпывая свой метод act () до того, как главный даже попытается их убить, поэтому на самом деле убивать подчиненных не требуется.

GPars предлагает метод terminate () для акторов, чтобы аккуратно их убить, поэтому вы можете подумать об изменении своего метода на: void killTheSlaves() { for (i in 0..slaves.size()-1){ slaves[i].terminate() } }

person Vaclav Pech    schedule 29.11.2016
comment
Проклятие! Теперь, когда вы на это указали, это абсолютно очевидно. Большое спасибо! Мой исходный код делает немного больше, чем просто печать, поэтому я надеюсь, что, по крайней мере, не все ведомые устройства завершат работу самостоятельно до того, как мастер завершит их. Для размещения здесь я немного сократил код. - person hsvar; 29.11.2016