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;
    }       
}

我计算名为“chi”的值,并基于此,如果“chi”小于“edgeCHI”值,我将密钥保存在实例变量中。该方法被一些线程调用,所以我强制同步。

当所有线程完成时,程序通过将控制权传递给控制操作顺序的方法继续执行。然后这一行已在该方法中执行:

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

它打印了正确的“chi”值,就像在decryptMessage方法中打印了“chi”的最后一个值一样,但是键的值不同。'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方法以识别最可行的解密密钥。这两天我一直在试图弄清楚问题是什么,但我不明白。建议?

4

2 回答 2

1

依靠 syserr(或 sysout)打印来确定执行顺序是危险的——尤其是在多线程环境中。当打印实际发生或打印的消息是否有序时,绝对没有保证。也许您看到的其中一个线程的“最后一个”打印消息不是修改关键字段的“最后一个”线程。你不能只看 sterr 输出就这么说。

您可以做的是对关键字段使用同步设置器,每当修改字段时都会增加关联的访问计数器并打印新值以及修改计数。这样您就可以避免 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 + " +");
}   

为了提供答案,我们需要查看更多控制线程执行的(必要时简化的)代码。

于 2012-09-27T21:37:31.457 回答
0

已找到解决方案。我只是在字段变量获得正确键的位置将CopyOnWriteArrayList数据类型更改为 ArrayList。它现在按预期工作。

于 2012-10-02T16:48:30.540 回答