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);
}