我继承了一个项目,在这个项目中,我们使用java并在图像上绘制内容。当用户来回移动滑块以更改图像上边缘的阈值时,它会运行一个检测该阈值的方法。这需要200-300ms的时间,所以它会锁定UI一段时间,但当用户移动滑块时,它会不断锁定界面。
他们似乎已经将其移动到后台线程,但每次滑块移动时,它都会创建一个新线程。因此,当用户移动滑块时,可能会产生80个线程,整个系统会锁定几秒钟。
我不确定如何解决这个问题。它是一个swingworker线程,可以回发到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.");
}
}
}这是单线程执行器服务的任务吗?我似乎找不到很多关于停止任务但继续使用相同线程的信息(例如,我认为是状态模式)。如果可能的话,我不想旋转一堆线程。
发布于 2015-06-25 03:26:30
问题可能是在SwingWorker中完成的工作是不可中断的,即在doInBackground() Thread.interrupted()中没有被检查。因此,即使您取消了工作进程,它实际上并没有停止,但仍然会继续产生一个结果(最终会被丢弃)。
可能解决此问题的一种方法是修改代码(最有可能是在detectEdges()内部)以及时响应中断。
如果这不是一个可行的选择,那么改变方法。如果有活动的工作进程,请跟踪;如果有,则向其提交新的参数集,否则启动一个。然后,worker本身需要修改,以便只在生成与当前参数匹配的结果后才退出doInBackground()。这种方法可能更容易手工实现,也就是说,不使用SwingWorker。
https://stackoverflow.com/questions/31034129
复制相似问题