Replace it unconditionally in the top level of the defining script. Something like this:
class myClass():
__init__(self, prior):
# Copy important values from prior version, as long as they
# are platform data types. Stop any threads stored in prior
# and remove any of its listeners from the platform.
pass
# Get the persistent global dictionary
_g = system.util.getGlobals()
# Protect the swap with a lock. Locks are defined by
# the jython stdlib, so do not have to be replaced on restarts.
# Use setdefault for assignment to ensure atomicity.
singletonLock = _g.get('singletonLock', None)
if singletonLock is None:
import thread
singletonLock = _g.setdefault('singletonLock', thread.allocate_lock())
# Swap old and new under the lock. This prevents
# races amongst multiple scripting contexts importing this script
# simultaneously. Just note that a new version might be replaced by
# another script context as soon as the lock is released.
with singletonLock:
_g['singletonKey'] = myClass(_g.get('singletonKey', None))
# Use the following pattern in functions where you need to use the
# singleton. Whatever you do, never sleep or do long calculations
# while holding the lock.
# with singletonLock:
# c = _g[singletonKey]
# # Do something with c