Late to the discussion but just want to shed some light on this. This discussion has been held before.
Volatile fields are not required for STATIC references because there is an implicit lock in the execution path from BundleContext.getService to the instance. Since this is the only way you can officially get an instance it is perfectly safe to not make the field volatile. The spec prescribes or implies the following: The activation is executed exactly once No caller of getService can see the object before activate has finished So what must happen under the hood Tscr: Register Service Factory SF for S Tscr: notify service event T1 -> getService S T2 -> getService S Since the spec mandates that an activate for instance I must be run exactly once AND you cannot access an unactivated instance, SF MUST have a lock. Since T1 was first, it gets it, T2 is blocked T1: get lock L -> pass T2: get L -> block T1: create instance I T1: inject fields in I T1: activate I T1: unlock L T2: get lock L -> pass T2: get initialized instance I T2: unlock L T2: use I T1: use I Since I can only be reached through the getService call, which will call the ServiceFactory.getService, it is impossible for a thread Tx to not pass the lock in the Service Factory SF for S. Thus, T2 always sees I after T1 finished activating it. Ergo, there is no need to use volatile for a static variable. Kind regards, Peter Kriens