我在取消Future
时遇到问题。首先让我解释一下情况。我正在制作一个基于某些参数生成图像的程序。这些图像可用鼠标“平移”。我的意思是,用户可以拍摄并拖动图像以显示不同的部分(就像通常那样)。每次用户平移时,都必须计算一个新图像。对于某些参数,这可能会花费一些时间,因此请执行以下操作。
ThreadPool
的图像(但尚未完成),它们将被取消(有关详细信息,请参见下文)。之后,我们按照点1处理锅。如果我进行少量更改(但仍然太多以至于无法计算每张图像),这将非常有用。例如,如果我进行了两次快速更改,则程序会快速计算出低分辨率的图像,并从高分辨率的图像开始。在完成高分辨率之前,用户需要进行新的更改。这将触发取消高分辨率图像,然后启动一个新的低分辨率图像,最后启动一个新的高分辨率图像。这可行。
当我抓起图像预览并像疯子一样开始平移时会出现问题。现在,期货偶尔会被取消,而当我停止平移时,我最终会得到大量的线程,试图计算应该被取消的高分辨率图像。是什么原因造成的?我也尝试在下面编写一些代码来解释我的问题。
public class Test {
ExecutorService threadPool = Executors.newFixedThreadPool(8);
private ArrayList<Future<WritableImage>> highResFutureList = new ArrayList<Future<WritableImage>>();
private ArrayList<Future<WritableImage>> lowResFutureList = new ArrayList<Future<WritableImage>>();
public static void main(String[] args) {
xAndYProperty.addListener(//ChangeListener that calls updateLowResImage());
}
public void updateLowResImage() {
if(lowResFutureList.size() != 0) {
for(Future<WritableImage> future : lowResFutureList) {
//I do not want low res images that have begun calculation to cancel, thus false.
System.out.println("Attempting low res cancel: " + fure.cancel(false));
}
}
if(highResFutureList.size() != 0) {
for(Future<WritableImage> future : highResFutureList) {
//I do want high res images that have begun calculation to cancel, thus true.
System.out.println("Attempting high res cancel: " + future.cancel(true));
}
}
new Thread(new Runnable() {
@Override
public void run() {
Future<WritableImage> future = threadPool.submit(getImageTask(lowResolution, lowResolution));
lowResFutureList.add(future);
try {
setImage(future.get());
System.out.println("Low res Future completed.");
} catch (Exception e) {
e.printStackTrace();
System.out.println("Low resolution Future cancelled.");
} finally {
lowResFutureList.remove(future);
}
}
}).start();
int resolution = (int) resolution.getValue();
if(resolution > lowResolution) {
new Thread(new Runnable() {
@Override
public void run() {
updateHighResImage(resolution);
}
}).start();
}
}
public void updateHighResImage(int resolution) {
EnhancedCallable<WritableImage> task = getImageTask(resolution, resolution);
task.setDescription("Updating " + name);
Future<WritableImage> future = threadPool.submit(task);
highResFutureList.add(future);
try {
setImage(future.get());
System.out.println("High res Future completed.");
} catch (Exception e) {
e.printStackTrace();
System.out.println("High resolution Future cancelled.");
} finally {
highResFutureList.remove(future);
}
}
public Callable<WritableImage> getImageTask(int width, int height) {
return new EnhancedCallable<WritableImage>("Generating " + name) {
@Override
public WritableImage call() {
//Making image in nested for loop...
for(int i = 0; i < width; i++) {
for(int j = 0; j < height; j++) {
//Calculating pixel values...
if(Thread.currentThread().isInterrupted()) {
System.out.println("INTERRUPTED!");
return null;
}
}
}
return image;
}
};
}
}
编辑:我还应该提到我是Futures
的新手,所有与之相关的事情对我来说都很轻松。