我已經繼承了一個項目,我們使用java並在圖像上繪製東西。當用戶來回移動滑塊來改變圖像邊緣的閾值時,它會運行一種檢測這種情況的方法。這需要200-300ms的時間,所以它將UI鎖定了一段時間,但隨着用戶移動滑塊,它不斷鎖定界面。在java中取消並重用一個(SwingWorker)線程
它們似乎已將其移至後臺線程,但每次滑塊移動時都會創建一個新線程。所以當用戶將滑塊移動一英寸時,它會產生80個線程,整個系統會鎖定幾秒鐘。
我不知道如何解決此問題。這是一個回發到UI的迴轉工作線程。我試着取消(),然後再次執行()該線程,但它似乎不可能。我不想要很多線程時,我可以取消舊的(因爲我們不需要舊的預覽),所以我認爲只有一個會工作。
這是工作者線程。
// WORKER
private class ThresholdWorker extends SwingWorker<BufferedImage, Object> {
// long-running code to be run in a worker thread
@Override
public BufferedImage doInBackground() throws Exception {
@SuppressWarnings("static-access")
BufferedImage img = new BufferedImage(imagePanel.rect_width, imagePanel.rect_height, BufferedImage.TYPE_3BYTE_BGR);
img = imagePanel.detectEdges();
return img;
} // end method doInBackground
// code to run on the event dispatch thread when doInBackground returns
@Override
protected void done() {
try {
@SuppressWarnings("static-access")
BufferedImage Img = new BufferedImage(imagePanel.rect_width, imagePanel.rect_height, BufferedImage.TYPE_3BYTE_BGR);
Img = get();
imagePanel.standardRectEdgesDilated = Img;
imagePanel.repaint();
} catch (InterruptedException ignore) {
} catch (ExecutionException ex) {
IdentiFrog.LOGGER.writeException(ex);
System.err.println("Error encountered while performing calculation.");
}
}
}
這是單線程執行程序服務的任務嗎?我似乎無法找到關於停止任務的大量信息,但仍繼續使用相同的線程(例如我認爲的狀態模式)。如果可能的話,我不想旋轉一堆線程。
我不知道某種生產者 - 消費者可能無法更好地與生產者作爲GUI和消費者是運行在後臺SwingWorker線程中的另一個長期運行的代碼。您的GUI會將映像更改請求排隊到消費者可以接受的隊列上,進行更改,然後傳回GUI。如果有足夠的請求堆疊到隊列中,則可以跳過其中的大部分請求並僅執行最近的請求。 –
請注意,我的建議有點類似於Swing自己的重繪管理器。 –
後臺線程如何在運行長時間運行的任務時檢查隊列的大小(例如縮放大圖或其他東西)? – Mgamerz