2014-03-28 27 views
5

我正在開發一個涉及邏輯電路仿真的項目(Java 8中)。電路在我用ANTLR v4解析的輸入文件中描述。爲什麼要調用虛函數修復一個錯誤?

使用ANTLR的訪客類,我建立了一個複合結構,存儲所有必要的組件來模擬電路。

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

然後,我初始化此電路到任何用戶指定的輸入端,但爲了簡單起見,我將它們初始化爲假(假設有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(); 

所有這一切工作完美 M上ac 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上運行時,同樣的代碼精確也會失敗。

UPDATE 2:我以前是錯的。現在看來,該程序只能在緩慢的機器上正常運行。它在調試器中運行,或者與我的開發平臺中Core i7相比處理速度慢的Macbook Air運行。這一定是相當的競爭條件。

+0

您正在使用哪個版本的Java? ('java -version')你是直接從'javac'編譯還是使用Eclipse的(或其他IDE的)編譯器? – Jeffrey

+3

你能把這個問題作爲SSCE發佈嗎?我們希望能夠自己測試它,並且我們不能用你當前的代碼來做到這一點,如果它們對執行本身無關緊要,我們也不會對你的類感興趣。 – skiwi

+0

[SSCCE](http://www.sscce.org/)鏈接,以防OP不知道它是什麼。 – Jeffrey

回答

0

好的,感謝所有在評論中的幫助。最終,在我們的評估模型中,這是一個「競爭條件」(該程序是單線程的)。我們正在使用優先級隊列,但未正確檢查重複的衝突條目。例如,在未定義的時間有可能將衝突的信號發送到相同的邏輯門。

這可能是我在編寫Java代碼時遇到的最奇怪的錯誤,至少在它如何呈現它自己的時候。

+0

有意思,因此,澄清一下,聽起來問題是相同優先級的PriorityQueue元素之間的排序是未定義的。那對嗎? –

+0

@StuartMarks它似乎是在javadoc中以這種方式定義:*該隊列的頭部是與指定排序相關的最少元素。如果多個元素的值最小,那麼頭是其中一個元素 - 任意斷開連接。*,位於http://docs.oracle.com/javase/8/docs/api/java/util/PriorityQueue。 html – skiwi

+1

對,我的問題是模擬器是否可能無意中依賴於特定的順序。 –

相關問題