我正在使用 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”值,我将 key 保存在实例变量中。该方法由某些线程调用,因此我强制同步。
当所有线程完成时,程序通过将控制传递给控制操作顺序的方法来继续执行。然后这一行已在该方法中执行:
System.err.println(edgeCHI+" "+key+" -");
它打印了正确的“chi”值,就像在 decryptMessage
处打印了“chi”的最后一个值一样。方法,但key的值不同。 “decryptMessage”方法已被生成键值的线程调用。
我将键值存储为全局变量
private volatile CopyOnWriteArrayList<Integer> key = null; // stores the most suitable key for decryption
。
为什么我有两个不同的键值?值(value)观本身并不重要。问题在于,最后一次调用“decryptMessage”方法时打印的 key 值(当 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 方法来识别最可行的解密 key 。 这两天我一直想弄清楚问题是什么,但我不明白。 有建议吗?
最佳答案
依赖 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;
}
并在内部解密消息:
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 + " +");
}
为了提供答案,我们需要查看更多控制线程执行的代码(如有必要,进行简化)。
关于java - 从字段变量读取值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12629408/