我已经继承了一个项目,我们使用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