为什么调用虚函数修复错误?

时间:2014-03-28 21:13:31

标签: java garbage-collection java-8

我正在开发一个涉及逻辑电路仿真的项目(Java 8)。这些电路在我用ANTLR v4解析的输入文件中描述。

使用ANTLR的访问者类,我构建了一个Composite结构,它存储了模拟电路所需的所有组件。

// module is an ANTLR parse tree
BLXCircuit mainCircuit = modelGenerator.visit(module);

之后,我将此电路的输入初始化为用户指定的任何内容,但为简单起见,我将它们初始化为false(假设有3个输入):

Map<BLXSocket, Boolean> valueMap = new HashMap<>();
List<BLXSocket> inputs = mainCircuit.getInputSockets();
valueMap.put(inputs.get(0), false);
valueMap.put(inputs.get(1), false);
valueMap.put(inputs.get(2), false);

然后我启动评估者:

BLXEventManager eventManager = new BLXEventManager(valueMap, 500);
eventManager.start();

所有这些在Mac OS X上都可以 完美 ,但是当我在Windows或Linux上运行时,评估只是......通过返回错误值而无声地失败。该程序正常退出,输出错误的计算。

然而,这是我的问题,如果我定义函数:

private static void noAction(BLXSignalReceiver unused) { }
private static void whyDoesThisFixThings(BLXCircuit blxCircuit) {
    for (BLXSocket blxSocket : blxCircuit.getInputSockets()) {
        blxSocket.getTargets().forEach(Main::noAction);
    }
}

并在声明mainCircuit

之后添加对此函数的调用
BLXCircuit mainCircuit = modelGenerator.visit(module);
whyDoesThisFixThings(mainCircuit); // why??

然后Windows和Linux都会表现出正确的行为。为什么这可能是?

编辑:我还发现这个代码在调试器下的运行方式与其自身不同(不是更好,必然)。

UPDATE :我重写了在Java 7上运行的所有代码,而没有改变它的语义。它现在可以在JDK 7上正常运行。在Java 8上运行时,完全相同的代码也会失败。

更新2 :之前我错了。现在看来该程序仅在慢速机器上正确运行。它可以在调试器或Macbook Air上运行,与我的开发平台中的Core i7相比,它的处理器速度较慢。这一定是一场竞争条件。

1 个答案:

答案 0 :(得分:0)

好的,感谢评论中的所有帮助。最终,这是一个&#34;竞争条件&#34; (我们的评估模型中的程序是单线程的)。我们使用优先级队列而没有正确检查重复的冲突条目。例如,冲突信号有可能在未定义的时间发送到同一逻辑门。

这可能是我在编写Java代码时遇到的最奇怪的错误,至少在它出现的过程中是这样。