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