Java-取消期货

时间:2018-07-11 14:20:07

标签: java future executorservice callable cancellation

我在取消Future时遇到问题。首先让我解释一下情况。我正在制作一个基于某些参数生成图像的程序。这些图像可用鼠标“平移”。我的意思是,用户可以拍摄并拖动图像以显示不同的部分(就像通常那样)。每次用户平移时,都必须计算一个新图像。对于某些参数,这可能会花费一些时间,因此请执行以下操作。

  1. (如果程序处于空闲状态。)当需要更新的图像时,将计算出低分辨率图像以向用户提供即时反馈。完成此操作后,程序将在高分辨率图像上启动。
  2. 如果有已提交到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的新手,所有与之相关的事情对我来说都很轻松。

0 个答案:

没有答案