【问题标题】:What ordering guarantees are provided on ServiceListener and ServiceTracker calls?ServiceListener 和 ServiceTracker 调用提供了哪些排序保证?
【发布时间】:2010-02-05 21:06:21
【问题描述】:

我试图了解为服务事件提供了哪些保证。

OSGi 规范说 ServiceEvents 是同步的,我认为这意味着 ServiceListener 不会收到带有 UNREGISTERING ServiceEvent 的 serviceChanged() 调用,直到带有 REGISTERED ServiceEvent 的 serviceChanged() 调用完成。这是正确的吗?

我还查看了 ServiceTracker 的源代码。它似乎试图应对这两个 serviceChanged() 调用重叠的情况。这可能吗?

对 ServiceTrackerCustomizer 的调用是否有任何类似的保证?

【问题讨论】:

    标签: java service osgi


    【解决方案1】:

    这是一个非常棘手的问题。当服务在 OSGi 中注册时,会处理事件并通知所有相关方(服务侦听器、服务跟踪器和声明式服务运行时)。每个相关方都有机会处理该事件。处理事件可以包括注册或注销附加服务。由于 ServiceEvent 通知的同步行为,这些事件随后被分派给相关方。在一个长的依赖链中,你最终会得到一个通知树,在那里你注册一个服务,它会导致一大堆新人注册。我知道这一点是因为它可以使性能调整 OSGi 启动成为一项非常具有挑战性的练习,因为您的简单注册服务调用会为未知数量的服务的服务激活付费。

    要具体回答您的问题,它不是与事件的多线程问题,而是可重入问题。那就是处理您的注册事件的人可能会在处理完整树之前通过另一个事件通知回到您身边。这是他们强烈建议您永远不要在持有锁时注册或取消注册服务的原因之一,否则您可能会死锁事件调度程序线程。保持安全的另一个好方法是使用捆绑依赖树,而不是图。包之间的循环依赖,即使类编译也可能导致真正的问题。

    我希望这会有所帮助。如果您想了解更多关于这类事情的信息,有一本关于 OSGi 和 Equinox 的新书即将出版。它现在可以在粗剪中使用,并且应该很快可以印刷。 http://my.safaribooksonline.com/9780321561510

    【讨论】:

    • 为了在启动期间避免这些事件风暴并保持一点秩序,您可以使用 startlevels。​​
    • 如果服务 A 已注册,那么每个感兴趣的 ServiceListener 都会收到一个 serviceChanged() 调用,其中包含该服务的 REGISTERED 事件。在处理 REGISTERED 事件时,是否有可能为 same service A 获得一个带有 UNREGISTERING 事件的 re-entrant serviceChanged() 调用?我看不到这是可能的,因为您需要 ServiceRegistration 来取消注册服务,并且在注册完成后才可用,但是......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多