Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 对函数的调用被卡住了,但监视器似乎被释放了,如何释放?_Java_Parallel Processing - Fatal编程技术网

Java 对函数的调用被卡住了,但监视器似乎被释放了,如何释放?

Java 对函数的调用被卡住了,但监视器似乎被释放了,如何释放?,java,parallel-processing,Java,Parallel Processing,我在一个项目中有以下设计 多爬虫 查找到的图像的列表(可观察的)ImageList;它通过线程化进程更新(因此是并行的) 两个观察者收听列表(Downloader和ImagesWindow);警告:这些可以被多次通知,因为列表是由线程更新的 我一直只想从ImageList中获取最新的条目,所以我用计数器实现了它: public class ImageList extends Observable { private final ConcurrentMap<Integer, Im

我在一个项目中有以下设计

  • 多爬虫
  • 查找到的图像的列表(
    可观察的)
    ImageList
    ;它通过线程化进程更新(因此是并行的)
  • 两个观察者收听列表(
    Downloader
    ImagesWindow
    );警告:这些可以被多次通知,因为列表是由线程更新的
我一直只想从
ImageList
中获取最新的条目,所以我用计数器实现了它:

public class ImageList extends Observable {
    private final ConcurrentMap<Integer, Image> images = new ConcurrentHashMap<Integer, Image>();
    private final AtomicInteger counter = new AtomicInteger(0);

    /* There is some more code within here, but its not that important
       important is that stuff gets added to the list and the list shall
       inform all listeners about the change

       The observers then check which is the newest ID in the list (often +1
       but I guess I will reduce the inform frequency somehow)
       and call (in synchronized method):

       int lastIndex = list.getCurrentLastIndex();
       getImagesFromTo(myNextValue, lastIndex);
       myNextValue = lastIndex + 1;
    */

    public synchronized void addToFinished(Image job) throws InterruptedException {
        int currentCounter = counter.incrementAndGet();

        images.put(currentCounter, job);

        this.setChanged();
        this.notifyObservers();
    }

    public synchronized int getCurrentLastIndex() {
        return counter.get();
    }

    public ArrayList<Image> getImagesFromTo(int starting, int ending) {
        ArrayList<Image> newImages = new ArrayList<Image>();

        Image image;
        for (int i = starting; i <= ending; i++) {
            image = images.get(i);
            if (image != null) {
                newImages.add(image);
            }
        }

        return newImages;
    }
}
但是,有时循环会被卡住,并且似乎允许对该方法进行第二次调用。然后就是这样:

  • Downloader检索图像70到70
  • Downloader检索图像70到71
  • 下载程序检索图像70到72
  • Downloader检索图像70到n
因此,允许第二次调用该方法来输入该方法,但计数器
readImageFrom
永远不会更新

当我删除对循环中其他函数的两个调用时,脚本开始工作。我知道它们没有同步,但如果“父级”已经同步,它们是否必须同步

filter.isOK()
是这样实现的(其他函数只返回true或false;如果包含
hasRightColor
,代码将失败,我想这是因为计算速度有点慢):

这怎么会发生?Eclipse不显示任何抛出的异常(这当然会导致方法退出)


可能还有一种完全不同的方法,只从多个观察者那里获取列表的最新内容(因为程序并行运行,每个观察者可能会收到几次通知)

好的,错误是一些恶意的NullPointerException,没有显示给我(谁知道为什么)在
filter.isOk()

我无法在IDE中看到它,因为我已从
this.image
更改为参数传递
image
,但忘记删除标题中的
私有图像
,并更改三个函数中最后一个函数的参数

所以eclipse既没有提到丢失的
图像
,也没有提到未使用的
this.image


最后。

哪个类包含
downloadNewImages
方法?这个类有多少个实例?readImageFrom声明在哪里?
downloadNewImages
包含在
Downloader
中(两个观察者之一)。只有一个
Downloader
(和另一个观察者的一个实例
ImagesWindow
)。
readImageFrom
在每个观察者中声明一次(意思是
Downloader
有一个
readImageFrom
ImagesWindow
有一个
readImageFrom
;每个都告诉这个观察者已经看到了多少元素)。
@Override
public void update(Observable o, Object arg) {
    System.out.println("Updated downloader");

    if (o instanceof ImageList) {
        ImageList list = (ImageList) o;
        downloadNewImages(list);
    }
}

private synchronized void downloadNewImages(ImageList list) {
    int last = list.getCurrentLastIndex();

    for (Image image : list.getImagesFromTo(readImageFrom, last)) {
        // code gets stuck after this line
        if (filter.isOk(image)) {
            // and before this line
            // [here was a line, but it also fails if I remove it]
        }
    }

    // set the index to the new index
    readImageFrom = last + 1;
}
public boolean isOk(Image image) {
    return hasRightDimensions(image) && hasRightColor(image);
}