2016-11-23 1 views
1

Я работаю над программой в течение нескольких недель, и кто-то дал мне предложение о том, как улучшить производительность, которую я пытаюсь реализовать. Это пока работает, но я столкнулся с проблемой, что я не могу прокомментировать один из вызовов println, которые я ранее добавил, чтобы помочь отлаживать и получать желаемый результат. код в вопросеУдаление вызова println в java вызывает логическую ошибку

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 класса, и он выполняется как отдельный поток из основной программы.

код в методе 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 в приведенном выше коде комментируется.

+0

«работает, как ожидалось», как вы ожидаете, что это работает? –

+2

'код ниже не делает, и вместо этого программа вообще не производит вывод. Ну, очевидно, вторая программа не выводит результат, потому что вы удалили оператор' println() ', правильно? – stackoverflowuser2010

+1

'System.out.println' внутренне синхронизирован. Это может вызвать разницу. –

ответ

2

Очень сложно проанализировать проблему, не имея возможности ее запустить.

Мое предположение было бы синхронизировать 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) { 
    ... 
} 
+0

Я думаю, вы должны добавить код, чтобы показать, как это должно быть сделано. Я не думаю, что OP знает, как это сделать. Вы можете добавить 'synchronized (this/* или использовать syncobject * /) {/ * ваш код * /}' –

+0

, работающий над этим ... done [:-) –

+0

спасибо, синхронизация 'alertComplete' решила проблему.tbh, я не знаю, почему я не столкнулся с проблемой в более ранних версиях программы. – user2209743

Смежные вопросы