我在项目中有以下设计
ImageList
(Observable
);这会由线程进程(因此并行)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
)使用这样的方法:
@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;
}
但是,有时循环会卡住,并且方法上似乎允许第二次调用。然后就是这样:
因此,允许第二次调用该方法,但计数器readImageFrom
永远不会更新。
当我删除对循环中其他函数的两次调用时,脚本开始工作。我知道他们没有同步,但如果已经“父”同步了,他们必须这样做吗?
filter.isOK()
是这样实现的(其他函数只返回true或false;当我包含hasRightColor
时代码失败,我猜因为它的计算速度有点慢):
public boolean isOk(Image image) {
return hasRightDimensions(image) && hasRightColor(image);
}
这怎么可能发生? Eclipse不会显示任何抛出的异常(当然会导致退出该方法)。
也许还有一种完全不同的方法,只能从多个观察者那里获取列表的最新内容(每个观察者可能多次通知因为程序并行运行)?
答案 0 :(得分:0)
好的,错误是一些邪恶的 NullPointerException ,filter.isOk()
中没有向我显示(谁知道原因)。
我无法在我的IDE中看到它,因为我已从this.image
更改为参数传递image
,但忘记删除标题中的private image
并更改三个函数中最后一个的参数。
因此,eclipse既没有说明遗失image
也没有说明未使用的this.image
。
最后。