2012-09-27 34 views
0

我正在開發Java 7中的桌面應用程序。我在這裏有一種情況。在低於從字段變量讀取值

private synchronized void decryptMessage 
    (CopyOnWriteArrayList<Integer> possibleKeys, ArrayList<Integer> cipherDigits) 
{ 
    // apply opposite shift algorithm: 
    ArrayList<Integer> textDigits = shiftCipher(possibleKeys, cipherDigits); 

    // count CHI squared statistics: 
    double chi = countCHIstatistics(textDigits); 

    if(chi < edgeCHI) // if the value of IOC is greater or equal than that 
    { 
     System.err.println(chi + " " + possibleKeys + " +"); 
     key = possibleKeys; // store most suitable key 
     edgeCHI = chi; 
    }  
} 

的方法我指望所謂的「志」和根據,如果「智」小於'edgeCHI的價值我保存在實例變量鍵的值。該方法由一些線程調用,所以我強制執行同步。

當所有線程完成程序繼續執行時,通過將控制傳遞給控制操作順序的方法。然後這條生產線在該方法被執行:

System.err.println(edgeCHI+" "+key+" -"); 

它打印「智」的正確的值,如已在decryptMessage方法被打印「智」的最後一個值,但密鑰的值是不同的。 'decryptMessage'方法由生成鍵值的線程調用。

我將關鍵值存儲爲全局變量 private volatile CopyOnWriteArrayList<Integer> key = null; // stores the most suitable key for decryption。 爲什麼我有兩個不同的鍵值?價值本身並不重要。問題是在上次調用'decryptMessage'方法時(當chi < edgeCHI)必須匹配在控制操作流程的方法上打印的鍵值。 這是你如何創建線程

for(int y = 0; y < mostOccuringL.length; y++){// iterate through the five most frequent letters 
       for(int i = (y + 1); i < mostOccuringL.length; i++){//perform letter combinations 
        int [] combinations = new int[2]; 
        combinations[0] = y; 
        combinations [1] = i;     
        new KeyMembers(""+y+":"+i ,combinations, keywords, intKeyIndex, cipherDigits).t.join(); 
       } 
      } 

在run方法調用decryptMesssage方法,以確定最可行的解密密鑰。 我一直在試圖弄清楚兩天的可能性是什麼,但我不明白。 建議?

+0

你期望的結果是什麼?你得到了什麼?我們不知道你在談論什麼兩個不同的關鍵值。 –

回答

0

解決方法已找到。我只是將CopyOnWriteArrayList數據類型更改爲ArrayList,其中字段變量獲得正確的密鑰。它現在按預期工作。

1

依靠syserr(或sysout)打印來確定執行順序是危險的 - 尤其是在多線程環境中。打印實際發生或打印的信息有序時絕對沒有保證。也許你看到的其中一個線程的「最後」打印的消息不是修改鍵字段的「最後」線程。你不能僅僅通過查看sterr輸出來說。

你可以做的是使用一個同步setter的關鍵字段,每當該字段被修改時增加一個關聯的訪問計數器,並打印新值和修改計數。這樣可以避免syserr打印的問題,並可靠地確定上一次設置的值。例如:

private long keyModCount = 0; 

private synchronized long update(CopyOnWriteArrayList<Integer> possibilities, double dgeChi) { 
    this.keys = possibilites; 
    this.edgeChi = edgeChi; // how is edgeChi declared? Also volatile? 
    this.keyModCount++; 
    return this.keyModCount; 
} 

而且裏面decryptMessage:

if(chi < edgeCHI) // if the value of IOC is greater or equal than that 
{ 
    long sequence = update(possibleKeys, chi); 
    System.err.println("["+ sequence +"]"+ chi + " " + possibleKeys + " +"); 
} 

提供答案,我們需要看到更多的(如果有必要簡化)代碼,控制線程的執行。

+0

'edgeCHI'沒有被聲明爲'volatile',但令人驚訝的是它存儲了正確的值作爲'decryptMessage'方法的sterr out流。您建議創建同步更新方法沒有什麼區別。 – uml

+0

從您顯示的代碼判斷,更新方法無法更改結果字段值。它唯一的目的是生成一個序列號,以在syserr輸出上建立一個總體排序,以便對相關變量進行更改。我仍然會將注意力放在對線程執行的「意外」重新排序作爲原因,但除非您提供更廣泛的執行流程和預期結果的概述,否則很難揭示它。你是否在代碼的其他部分檢查了密鑰字段(或存儲在那裏的列表)的修改? – Pyranja

+0

好的,那麼,那個'意外的'線程重新排序是什麼? – uml