java - 从字段变量读取值

标签 java multithreading field

我正在使用 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/

相关文章:

php - 如何将优惠券添加到 WooCommerce 产品页面

php - 我如何删除 http ://www in form?

java - 访问由字符串和数组组成的对象内的数组

multithreading - 多线程在单核系统上如何工作?

ios - 如何将整数发送到类型 id 的指针

java - Vertx多线程worker verticle不并行处理消息

orm - JPA中原生查询的字段值

java - 如何获取 Spring Restful Web 服务中请求正文中发送的字符串?

java - Glassfish 4 上的 Weld 001508 异常 : how to ignore interface(s)?

java - 子类间序列化