private final Object focusLock = new Object();
private final List<WeakReference<Action0>> focusedList = new ArrayList<>(4);
private static boolean DEBUG_FOCUS = true;
@Override
public void addMainStageFocused(Action0 focused) {
synchronized (focusLock) {
focusedList.removeIf(cur -> cur.get() == null || cur.get() == focused);
focusedList.add(new WeakReference<>(focused));
}
}
@Override
public void removeMainStageFocused(Action0 focused) {
synchronized (focusLock) {
focusedList.removeIf(cur -> cur.get() == null || cur.get() == focused);
}
}
@Override
public void notifyStageFocused() {
synchronized (focusLock) {
var it = focusedList.iterator();
while (it.hasNext()) {
var action = it.next(); //ConcurrentModificationException
var real = action.get();
if (real != null) {
real.invoke();
} else {
it.remove();
}
}
}
}
这段代码很经典的一个观察者,监听者。在notify通知的时候,会提示it.next() 出现ConcurrentModificationException。
反复google,反复地排查这个arrayList的锁的情况,或者换成syncList都一样报ConcurrentModificationException!即使我不做it.remove()也照样,会出现ConcurrentModificationException!
换成for也一样报错!
官方的说法,stackOverflow等,只有一条,你在迭代、循环的时候,改变了list。
最后,需要排查的是notify到具体某个监听者后面的执行逻辑,又调用了addMainStageFocused!
这也符合追加的日志,为何每次synchronized不能顺利走完这块{}一段的逻辑。
备注完毕。提个醒。消耗了1个小时的时间。