Java ServiceListener和ServiceTracker调用提供了哪些排序保证?

Java ServiceListener和ServiceTracker调用提供了哪些排序保证?,java,service,osgi,Java,Service,Osgi,我试图了解为服务活动提供了哪些保证 OSGi规范说ServiceEvents是同步的,我认为这意味着ServiceListener将不会收到带有未注册ServiceEvent的serviceChanged()调用,直到带有已注册ServiceEvent的serviceChanged()调用完成。这是正确的吗 我还查看了ServiceTracker的源代码。它似乎试图处理这两个serviceChanged()调用重叠的情况。这可能吗 对ServiceTrackerCustomizer的调用是否有类

我试图了解为服务活动提供了哪些保证

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

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


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

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

具体地回答你的问题,它不是一个多线程的事件,它是一个重新进入的关注。也就是说,在处理完整树之前,处理注册事件的人可能会向您发送另一个事件通知。这就是他们强烈建议您在持有锁时不要注册或取消注册服务的原因之一,否则您可能会使事件调度程序线程死锁。另一个保持安全的好方法是使用捆绑依赖树,而不是图形。捆绑包之间的循环依赖关系,即使类编译也会导致实际问题

我希望这有帮助。如果你想读更多关于这类事情的书,有一本关于OSGi和Equinox的新书即将出版。它现在可以在粗糙的削减,应该可以在印刷品很快。

为了避免启动过程中发生这些事件风暴,并保持一定的秩序,您可以使用StartLevel。如果注册了服务a,则每个感兴趣的ServiceListener都将获得一个serviceChanged()调用,其中包含该服务的已注册事件。在处理已注册事件的同时,是否可以为同一服务a获取具有注销事件的重新进入serviceChanged()调用?我认为这是不可能的,因为您需要一个ServiceRegistration来注销该服务,并且在注册完成后才可用,但是。。。