gpt4 book ai didi

java - 对函数的调用被卡住,但监视器似乎被释放了,怎么办?

转载 作者:行者123 更新时间:2023-12-01 05:14:30 25 4
gpt4 key购买 nike

我在项目中有以下设计

  • 多个抓取工具
  • 找到的图像的列表ImageList(Observable);这由线程进程更新(因此是并行的)
  • 两个监听列表的观察者(DownloaderImagesWindow);警告:这些可以被多次通知,因为列表是由线程更新的

我一直想从 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;
}
}

观察者(此处为下载器)使用此方法如下:

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

但是,有时循环会卡住,并且该方法似乎允许进行第二次调用。然后会发生这样的事情:

  • 下载程序检索图像 70 到 70
  • 下载程序检索图像 70 至 71
  • 下载程序检索图像 70 到 72
  • ...
  • 下载程序检索图像 70 到 n

因此,允许对该方法进行第二次调用,但计数器 readImageFrom 永远不会更新。

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

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

public boolean isOk(Image image) {
return hasRightDimensions(image) && hasRightColor(image);
}

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

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

最佳答案

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

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

所以 Eclipse 既没有说任何关于丢失的 image 的事情,也没有说任何关于未使用的 this.image 的事情。

终于。

关于java - 对函数的调用被卡住,但监视器似乎被释放了,怎么办?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11483181/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com