删除 java 中的 println 调用导致逻辑错误

Removing a println call in java is causing a logical error

我已经在一个程序上工作了几个星期,有人给了我一个关于如何提高我试图实施的性能的建议。到目前为止,它正在工作,但我有 运行 问题,我无法注释掉我之前添加的 println 调用之一以帮助调试并仍然获得所需的输出。有问题的代码是

if (distTable != null)
{
    //System.out.println("test");
    float [] distLine;
    for (int i = 0; i < s.emitters.length; i++)
    {
        int tx = s.emitters[i].getX();
        int ty = s.emitters[i].getY();
        for (int x = 0; x < matrix.length; x++)
        {
            distLine = distTable[Math.abs(x-tx)];
            for (int y = 0; y < matrix[x].length; y++)
            {
                    matrix[x][y] += s.emitters[i].amplitudeAtDist(distLine[Math.abs((y * targetThreads)+threadNumber - ty)]);
            }
        }
        System.out.println("test " + i + " " + threadNumber);
    }
    callback.alertComplete(this);
    return;
}

上面的代码按预期工作但是,下面的代码没有,而是程序根本不产生任何输出。唯一的区别是下面的代码有一个 println 调用被注释掉了。

if (distTable != null)
{
    //System.out.println("test");
    float [] distLine;
    for (int i = 0; i < s.emitters.length; i++)
    {
        int tx = s.emitters[i].getX();
        int ty = s.emitters[i].getY();
        for (int x = 0; x < matrix.length; x++)
        {
            distLine = distTable[Math.abs(x-tx)];
            for (int y = 0; y < matrix[x].length; y++)
            {
                    matrix[x][y] += s.emitters[i].amplitudeAtDist(distLine[Math.abs((y * targetThreads)+threadNumber - ty)]);
            }
        }
        //System.out.println("test " + i + " " + threadNumber);
    }
    callback.alertComplete(this);
    return;
}

以上代码是 Runnable class 中 运行 方法的一部分,它作为独立于主程序的线程执行。

最后调用的alertComplete方法中的代码是:

public void alertComplete(SimThread s) {
    completedThreads ++;
    int threadNumber = s.getThreadNumber();
    int targetThreads = s.getTargetThreads();
    double[][] temp = s.getResultMatrix();
    for (int x = 0; x < temp.length; x++)
    {
        for (int y = 0; y < temp[x].length && (y*targetThreads)+threadNumber < tempMatrix[x].length; y++)
        {
            double t = temp[x][y];
            tempMatrix[x][(y*targetThreads)+threadNumber] = t;
        }
    }
    if (completedThreads == MAXTHREADS)
    {
        System.out.println("Calculating points took " + ((System.currentTimeMillis() - startTime)) + " milliseconds.");
        normalizeAndDraw(tempMatrix);
    }

}

当上面代码中的println被注释时,此方法中的println调用不会执行。

无法运行分析问题是非常困难的。

我的猜测是同步 alertComplete,或者更好的是,同步对 completedThreads 的访问 - 最终问题是两个或多个线程同时更新计数器,所以它永远不会达到 MAXTHREADS。或者尝试使用 AtomicInteger 作为计数器...

但这只是一个非常粗略的猜测,因为我还没有完全了解...

假设计数器仅在 alertComplete 中使用,您可以这样做:

private final Object counterLock = new Object(); // could use any other existing (meaningfull) object

...

public void alertComplete(SimThread s) {
    bollean done;
    synchronized (counterLock) {
        completedThreads ++;
        done = completedThreads == MAXTHREADS;
    }

    ...

    if (done)
    {
        System.out.println("Calculating points took " + ((System.currentTimeMillis() - startTime)) + " milliseconds.");
        normalizeAndDraw(tempMatrix);
    }

}

或者只声明同步方法(用于测试):

public synchronized void alertComplete(SimThread s) {
    ...
}