删除 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) {
...
}
我已经在一个程序上工作了几个星期,有人给了我一个关于如何提高我试图实施的性能的建议。到目前为止,它正在工作,但我有 运行 问题,我无法注释掉我之前添加的 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) {
...
}