我正在寫一個Java程序,它使用遺傳算法將一組數字分成兩組,因此它們的總和相等或儘可能接近相等。程序應該在TextArea中追加每次迭代的結果。我不希望程序在計算時凍結,所以我把邏輯放在另一個線程中。更具體地說:JavaFX - 從另一個線程更新TextArea並丟失迭代
- 我創建了擴展任務的類Runner。 BestSpecimen是我的類,它用於此處打印迭代次數和此迭代中找到的最佳解決方案列表。它也更新ProgressBas,但並不重要。我通過在我的控制器類中添加以下行來完成它:runnerProgressPB.progressProperty()。bind(runner.progressProperty());
- 我想在更新TextArea時做同樣的事情,但是它不能正常工作。重點在於它使用當前迭代更新了TextArea,但刪除了之前迭代的結果。
- 我用不同的方法:在我的控制器類,我添加這段代碼:
runner.valueProperty().addListener((observable, oldValue, newValue) -> { resultsTA.appendText(newValue + "\n"); });
- 簡單,它只是監聽在線程中調用亞軍ValueProperty的變化。在創建在迭代過程中發生的BestSpecimen對象之後,我更新ValueProperty。然而,問題在於 - TextArea中缺少許多迭代。看看截圖。有一百多個迭代缺失! Screenshot
- 嗯,我在想什麼?線程運行速度如此之快以至於TextArea無法及時更新信息。我在for循環中加入了一些Thread.sleep(),減少了迭代次數,但程序運行非常緩慢!我使用了Thread.sleep(20),並花了5-10分鐘才完成,但仍有一些遺漏的迭代。這不是解決方案。
- 我想達到什麼目的?我想讓跑步者線程在設置ValueProperty後暫停並等待TextArea未更新。我想我應該使用wait()/ notify()構造,但不知道在哪裏。我很新的線程事物...
這是我的Runner類的call()方法中的主循環。在此之前,只有變量的聲明。
while (!this.done) { for (int i = 0; i < this.iterations; i++) { current = this.population.get(i); theBestOnes = current.getTheBestSpecimen(); bestCase = new BestSpecimen(i+1, theBestOnes); this.updateValue(bestCase); this.updateProgress(i, iterations); next = Population.createParentPopulationFromExistingOne(current); next.fillPopulation(); this.population.add(this.population.size(), next); } done = true; } return null;
順便提一下,也有這個討厭的空(見上面的屏幕快照),其被附加到文本區。任何想法如何我可以擺脫它?返回語句在方法結尾處重新提交,我無法返回沒有內容的BestSpecimen對象。
所有'updateXXX(...)'方法都是用來設置屬性的值,而不是提供值的流。因此,他們可能會將多個呼叫合併到一個呼叫中(特別是如果您在兩個相鄰幀渲染之間更新了多次值,可能會發生這種情況)。您需要明確附加到FX應用程序線程上的文本區域。 (請注意,如果您的輸出很大,文本區域可能不是最佳選擇。) –
我該怎麼做?我在另一個線程中運行我的計算,而我無法從這裏完成。我需要在每次迭代中更新我的TextArea,不僅在線程完成時。另外,我使用TextArea justo進行測試,將來會改變它。 – Patryk