java - 为什么调用虚拟函数会修复错误?

标签 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 都会表现出正确的行为。为什么会这样?

编辑:我还发现这段代码在调试器下的运行方式与它自己运行时不同(不一定更好,不一定)。

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

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

最佳答案

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

这可能是我在编写 Java 代码时遇到的最奇怪的错误,至少就它本身的表现而言是这样。

关于java - 为什么调用虚拟函数会修复错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22723313/

相关文章:

Java 编译器 : How can two methods with the same name and different signatures match a method call?

java - 为现有 Stream 添加新值(value)

java - 直接遍历 JAR 文件中的文件夹

java - JTextPane 动态缩进!!!情况

java - BlockingQueue 是否有最大阻塞时间

garbage-collection - 为什么 GC 不会自动处理我类(class)的成员?

java - J2SE JPA 持久性行为

c# - Windows Phone,即使只有弱引用,垃圾收集器也不会清理 View

java - 为什么从串行GC切换到G1会增加RSS

java-8 - 在 java 8 中触发元空间内存上的 gc