Java EventListenerList的线程安全性如何?

Java EventListenerList的线程安全性如何?,java,multithreading,events,event-handling,Java,Multithreading,Events,Event Handling,他们说他们提供“一定程度的MT安全性(当正确使用时)。”这是什么意思?我看到制作阵列副本可以保护您在开火时不会让东西自行移除,那么在什么情况下会失败呢 更具体地说,我正在尝试构建一个EventBus,以简化多线程应用程序中日益复杂的事件传递。我担心如果多个线程试图触发/响应事件,可能会发生什么情况,我还担心通过阻止机制强制执行安全性,因为我的线程的目的是防止我的UI阻止昂贵的任务。这不是非常线程安全的-((基于代码的名称。) 他们做对的事情: add和remove方法被标记为synchroniz

他们说他们提供“一定程度的MT安全性(当正确使用时)。”这是什么意思?我看到制作阵列副本可以保护您在开火时不会让东西自行移除,那么在什么情况下会失败呢


更具体地说,我正在尝试构建一个EventBus,以简化多线程应用程序中日益复杂的事件传递。我担心如果多个线程试图触发/响应事件,可能会发生什么情况,我还担心通过阻止机制强制执行安全性,因为我的线程的目的是防止我的UI阻止昂贵的任务。

这不是非常线程安全的-((基于代码的名称。)

他们做对的事情:

  • add
    remove
    方法被标记为
    synchronized
    ,因此对其中一个方法的调用不会与对另一个方法的调用同时发生
  • 侦听器列表数组从不被修改;
    添加
    删除
    始终为
    侦听器列表
    分配一个新数组
  • 他们做错的事情(不幸):

  • listenerList
    字段不是
    volatile
  • getListenerList()
    方法未
    synchronized

  • 这意味着,如果您在一个线程中调用
    add
    remove
    ,然后在另一个线程中调用
    getListenerList
    ,更改可能不会被观察到,并且您可能仍然会得到旧版本的侦听器列表。

    您对更好的替代方案有什么建议吗?我正在考虑使用ConcurrentSkipListSet,bu我不确定这是否能解决你关于做错事的两点,也不确定这是否能使你关于做错事的两点保持正确。事实上,我认为我可以忍受这种失败,如果一个或两个事件在添加时丢失,或者一对事件在删除时漏掉,这不会严重影响我的程序。谢谢。@Dogmatixed:好吧,如果其中一个是d如果您决定无法处理此问题,
    CopyOnWriteArraySet
    非常适合这种情况。@Chris,虽然需要volatile,但它是“swing”的内容,因此listenerList字段在某个时候是可见的(我忽略了将字段永久缓存到CPU寄存器中的选项)。因此,它最终将是一致的。但是,不能保证:但是,至少您永远不会观察到部分修改的侦听器列表。除非JVM对listenerList字段使用内部函数。读线程可以看到部分“添加”的侦听器,CPU可以重新排列
    tmp[i]=t;tmp[i+1]=l;listenerList=tmp;
    sequence。所以它不是线程安全的。@是的,你完全正确。我忘记了重新排序(我不应该忘记)。我会将我的答案恢复到第一个修订版。;-)实际上,我认为CPU访问重新排序不是线程安全的。不过,在x86上可能永远也看不到它。@bestsss:这不仅是你的观点,也是事实。:-)说真的,没有
    volatile
    是非常草率的-(