【发布时间】:2010-01-15 15:34:18
【问题描述】:
相关: Does java have a "LinkedConcurrentHashMap" data structure?
我正在寻找一个集合类来保存对事件侦听器的引用。
理想情况下,我希望该集合具有以下属性(按优先级排序):
- 维护插入顺序。较早的侦听器可能会取消该事件,从而阻止它被传递给后来添加的侦听器。如果使用诸如
HashSet之类的类,其迭代器可能以错误的顺序返回元素,这将中断。 - 使用
WeakReferences 以便侦听器列表不会阻止对侦听器进行垃圾收集。 - 集合是
Set,因此会自动删除重复项。 -
Iterator是集合的线程安全快照,不受添加新侦听器的影响。还允许在多个线程上传递事件。 (这不是必需的 - 我可以迭代该集合的克隆。)
我知道一些课程满足部分但不是所有这些标准。例子:
-
java.util.LinkedHashSet(#1 和 #3) -
java.util.WeakHashMap,由Collections.newSetFromMap包裹(#2 和#3) -
javax.swing.event.EventListenerList(需要一些额外的同步)(#1 和 #4) -
java.util.concurrent.CopyOnWriteArraySet(#1、#3 和 #4)
但是 #1 和 #2 都没有。这样的类是否存在于某个库中?
【问题讨论】:
-
监听器对象实现
equals真的很典型吗? -
另外,保留对每个听众的强烈引用是谁的工作?如果我写了一个监听器来记录各种事件并注册它,当它在几分钟后突然消失时,我肯定会感到惊讶!
-
没有等号的问题是:
{Object o = new Object(); WeakReference r1 = new WeakReference(o), r2 = new WeakReference(o); return r1.equals(r2);}返回false -
这对匿名监听器来说是个问题,但我的监听器是
ListModel,所以它们通常会被 GUI 强烈引用。 -
关于#2:我认为你不应该依赖垃圾收集来清理你的烂摊子。如果你在某个地方注册了一个监听器,你应该自己注销它,不要指望它会在某个时间点自动消失。通常,侦听器在触发时会执行某些操作,并且由于您无法知道垃圾收集何时开始,因此您将获得非常不确定的行为...
标签: java collections concurrency weak-references event-listener