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