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

标签 java multithreading println

我已经在一个程序上工作了几个星期,有人给了我一个关于如何提高我正在尝试实现的性能的建议。然而到目前为止,它正在工作,我遇到了一个问题,我无法注释掉我之前添加的用于帮助调试的 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 类中 run 方法的一部分,它作为与主程序分开的线程执行。

最后调用的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) {
    ...
}

关于java - 删除 java 中的 println 调用会导致逻辑错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40759043/

相关文章:

java - 使用 Feign 上传文件 - multipart/form-data

java - 静态分析期间检查/放置错误的非原子使用

Java打印包含整数的字符串

c++ - 来自目标线程的 PostThreadMessage

println - 在 Swift 中执行 println 字典项时转义字典键双引号

scala - Scala 中 println 的替代方案

Java IO 无法从 URL 找到现有文件

java - 如何在hadoop环境中添加外部Jar?

java - 如何在不同的 java IDE 中保持一组 ant 构建脚本的更新?

c++ - 这是启动和停止线程的安全方法吗?