ServiceListener 和 ServiceTracker 调用提供哪些顺序保证?
我试图了解为服务活动提供哪些保证。
OSGi 规范说 ServiceEvent 是同步的,我认为这意味着 ServiceListener 将不会接收带有未注册的 ServiceEvent 的 serviceChanged() 调用,直到带有注册的 ServiceEvent 的 serviceChanged() 调用完成。这是正确的吗?
我还查看了 ServiceTracker 的源代码。它似乎试图应对这两个 serviceChanged() 调用重叠的情况。这可能吗?
对 ServiceTrackerCustomizer 的调用是否有任何类似的保证?
I'm trying to understand what guarantees are provided for service events.
The OSGi spec says that ServiceEvents are synchronous, I've taken this to imply that a ServiceListener will not receive a serviceChanged() call with an UNREGISTERING ServiceEvent until the serviceChanged() call with a REGISTERED ServiceEvent has completed. Is this correct?
I've also had a look at the source for ServiceTracker. It seems to try to cope with the situation where those two serviceChanged() calls overlap. Is this possible?
Are there any similar guarantees on calls to a ServiceTrackerCustomizer?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这是一个非常棘手的问题。当服务在 OSGi 中注册时,事件将被处理并通知所有感兴趣的各方(服务侦听器、服务跟踪器和声明性服务运行时)。每个感兴趣的各方都有机会处理该事件。处理事件可以包括注册或取消注册附加服务。由于ServiceEvent通知的同步行为,这些事件随后被分派给感兴趣的各方。在长依赖链中,您最终会得到一棵通知树,您可以在其中注册单个服务,并导致一大堆新人注册。我知道这一点是因为它会使 OSGi 启动的性能调整成为一项非常具有挑战性的工作,因为您简单的注册服务调用会因未知数量的服务激活而付费。
具体回答您的问题,这不是对事件的多线程关注,而是一个可重入的关注。那就是处理您的注册事件的人可以在处理完整的树之前向您发送另一个事件通知。这是他们强烈建议您永远不要在持有锁时注册或取消注册服务的原因之一,否则可能会导致事件调度程序线程死锁。保持安全的另一个好方法是使用捆绑依赖树,而不是图表。包之间的循环依赖关系,即使类编译也会导致真正的问题。
我希望这有帮助。如果您想了解更多此类内容,可以阅读一本关于 OSGi 和 Equinox 的新书。该书现已提供粗剪版,并且很快就会印刷版。
http://my.safaribooksonline.com/9780321561510
This is a very tricky issue. When a service is registered in OSGi, the event is handled and all interesting parties are notified (service listeners, service trackers and declarative service runtime). Each interested party has a chance to handle the event. Handling the event can include registering or unregistering additional services. Due to the synchronous behavior of ServiceEvent notification, these events are then dispatched to the interested parties. In a long dependency chain you end up with a tree of notification, where you go to register a single service and it causes a whole bunch of new guys to get registered. I know this because it can make performance tuning OSGi startup a very challenging exercise, since your simple register service call got charged for the service activation of an unknown number of services.
To specifically answer your question, its not a multi-threaded concern with the events, its a re-entrant one. That is the guy processing your register event could get back around to you with another event notification before the full tree gets processed. This is one of the reasons that they strongly recommend that you never register or unregister services while holding locks, or else you can deadlock the event dispatcher thread. Another good way to stay safe is to have a bundle dependency tree, not a graph. The circular dependencies between bundles, even if the classes compile can cause real problems.
I hope this helps. If you want to read more on this sort of thing, there is a new book coming out on OSGi and Equinox. Its available on rough cuts now and should be available in print very soon.
http://my.safaribooksonline.com/9780321561510