停止模拟后,我偶尔会收到以下错误消息:
例:
Exception during stopping the engine:
INTERNAL ERROR(S):
Engine still has 6 events scheduled: 2386.0: [null]
java.lang.RuntimeException: INTERNAL ERROR(S):
Engine still has 6 events scheduled: 2386.0: [null]
at com.anylogic.engine.Engine.g(Unknown Source)
at com.anylogic.engine.Engine.stop(Unknown Source)
at com.anylogic.engine.ExperimentSimulation.stop(Unknown Source)
at com.anylogic.engine.gui.ExperimentHost.executeCommand(Unknown Source)
at com.anylogic.engine.internal.webserver.l.onCommand(Unknown Source)
...
我的模拟模型如下所示: 5台机器的仿真模型
该模型模拟作业车间调度问题,并执行以下操作:
- 通过源块中的
inject(20)
生成作业代理 - 作业转到数据库定义的计算机并在等待块中等待
- 作业由其他代理从等待块中释放出来
- 作业在服务块中处理
- 作业将该过程重复 4 次
步骤 3 中总共有 5 个代理 - 我们称它们为计划代理 - 它们使用Wait.free()
方法来释放代理。一个代理控制一个等待块。所有 5 个调度代理同时工作,并通过Main
代理进行同步(Main
通知调度代理)。保留块在模拟启动后立即解除阻止。它们的存在也是为了同步目的。每个调度代理都拥有自己的线程,该线程通过Thread.start()
由Main
中定义的超时事件(发生一次,时间 = 0)启动。
来自计划代理的线程如下所示:
new Thread(new Runnable() {
public void run() {
synchronized (sync_obj) {
sync_obj.waituntilJobarrives();
sync_obj.Waitblock.free(a_Job);
synv_obj.waituntilJobisfinished();
repeat();
}
}
});
现在这是我的问题:当我开始模拟时,作业会正常生成并移动到其分配的等待块。之后,计划代理开始工作并释放作业,但有时调度代理会调用Waitblock.free()
方法,并且作业不会设置为自由(在调用该方法时与traceln()
一起检查)。为了仔细检查问题,我实现了按钮,这些按钮手动调用Waitblock.free()
方法,但工作代理仍然不会离开等待块。如果代理未释放作业,则作业车间的模拟将卡在那里。模拟继续运行,但 20 个作业从未完成,并且不会显示错误消息(从技术上讲没有错误)。只有在停止模拟后,控制台中才会显示上面显示的错误消息。
更糟糕的是,这个错误并没有一直出现。有时模拟工作正常,有时等待块停止反应。通常,在模拟足够长的时间后,会出现此错误,并且一个或多个等待块停止反应。
我从阅读错误消息中猜测,引擎收到了将代理从等待块中释放出来的命令。它现在不会这样做。如何或可以控制引擎计划的事件顺序(个人学习版)?还是有另一种解决问题的方法?
我很感激任何帮助!
编辑:通过删除Hold-block
,Engine still has X events scheduled
的错误并不经常出现。但是"等待块"仍然没有响应Waitblock.free()
方法,控制台中出现以下错误消息:
java.lang.RuntimeException: root.w_Warteblock1.readyEntities.output.readyNotificationAsync.event: negative timeout: -1.25
at com.anylogic.engine.Engine.error(Unknown Source)
at com.anylogic.engine.EventOriginator.g(Unknown Source)
at com.anylogic.engine.EventOriginator.c(Unknown Source)
at com.anylogic.engine.EventTimeout.restart(Unknown Source)
at com.anylogic.libraries.processmodeling.AsynchronousExecutor_xjal.a(Unknown Source)
at com.anylogic.libraries.processmodeling.OutputBlock.notifyReady(Unknown Source)
at com.anylogic.libraries.processmodeling.OutputBuffer.a(Unknown Source)
at com.anylogic.libraries.processmodeling.OutputBuffer.take(Unknown Source)
at com.anylogic.libraries.processmodeling.Wait.free(Unknown Source)
这看起来更像是一个常见的错误,我可以捕获,因此,我当前的解决方法是在 Thread 周围使用 try 和 catch 块,该块调用Waitblock.free()
方法并使用保存在 excel 文件中的模拟进度重新启动模拟。
我会告诉你我的想法,但这些信息可能不足以得出结论:
我记得当我暂停模拟然后删除代理然后停止模拟时,我会收到此错误。如果我按照这些步骤操作,我会得到那个错误......
这意味着当您停止模拟时,您需要给模拟至少一毫秒的时间才能完成计划的事件......在这种情况下,您的计划事件位于线程上。因此,解决方案是在单击停止按钮之前使用 finishSimulation() 停止模拟。你必须在 finishSimulation() 函数运行之前杀死线程...我不确定这一点,但试一试。
这是第一个问题...我认为第二个问题与等待后的保留有关。请注意,如果您的保留块被阻止,并且您尝试从等待块中释放 1 个以上的代理...取消阻止保留时,只会释放 1 个代理。这是因为等待块的出口处只有 1 个代理的空间......如果您犯了这个错误,代理将永远留在等待块中。一种解决方案是在等待块之后使用队列。我不认为这个问题与您遇到的错误有关......
我在测试套件中遇到了这个问题。我通过调用来修复它:
engine.finish();
而不是:
engine.stop();