如何为Java集成的AnyLogic模型设置回调以替代轮询获取更新值
AnyLogic集成Java:使用回调替代轮询获取模型更新值
实现思路
通过在AnyLogic模型中定义回调接口,注册外部Java程序的实现类,当模型内目标值发生更新时主动触发回调,直接将新值推送给Java程序,避免轮询开销。
步骤1:定义回调接口
在Java项目中创建通用回调接口,用于接收模型的更新通知:
public interface ModelValueListener { // valueName:更新的模型值名称,newValue:最新值 void onValueUpdated(String valueName, Object newValue); }
步骤2:在AnyLogic模型中添加回调支持
在AnyLogic的Main agent类中添加回调注册和触发逻辑:
// 持有外部注册的回调实例 private ModelValueListener valueListener; // 供外部Java程序注册回调的方法 public void setValueListener(ModelValueListener listener) { this.valueListener = listener; } // 内部触发回调的工具方法 private void notifyValueUpdated(String valueName, Object newValue) { if (valueListener != null) { valueListener.onValueUpdated(valueName, newValue); } }
步骤3:在模型中触发回调
在AnyLogic模型里,每当目标值(变量、参数等)更新时,调用notifyValueUpdated方法推送新值:
// 示例:当模型中的myProductionRate变量更新时触发回调 myProductionRate = 150; // 此处为变量更新逻辑 notifyValueUpdated("myProductionRate", myProductionRate); // 也可在变量的"On change"事件中添加notify调用(AnyLogic可视化界面中设置)
步骤4:Java主程序实现并注册回调
在你的Java软件中,实现回调接口并注册到AnyLogic模型:
final Simulation anylogicSimulation = new Simulation(); Main mainAgent = (Main) anylogicSimulation.getEngine().getRoot(); // 实现回调逻辑 ModelValueListener updateListener = new ModelValueListener() { @Override public void onValueUpdated(String valueName, Object newValue) { // 处理模型传来的更新数据,执行业务操作 System.out.printf("模型[%s]更新为:%s%n", valueName, newValue); // 例如更新软件UI、写入数据库等 } }; // 将回调注册到模型 mainAgent.setValueListener(updateListener); // 启动模拟 anylogicSimulation.start();
注意事项
- 线程安全:AnyLogic模拟运行在独立线程中,回调方法会在模拟线程执行。如果Java程序涉及UI操作(如Swing、JavaFX),需使用对应线程调度工具(如
SwingUtilities.invokeLater)切换到UI线程执行,避免线程冲突。 - 灵活扩展:可根据需求定义更细粒度的回调接口(比如针对特定变量的单独方法),或支持注册多个监听器。
内容的提问来源于stack exchange,提问作者Piero
相关产品推荐
相关产品推荐

