I have a cache as a member variable in my service and I'm creating a method to expose it via a JMX MBean, so that I can tear down and recreate my vogon cache at runtime with a new cache expiry time:
public class CachedVogonService implements CachedVogonServiceMBean {
private LoadingCache<String, Vogon> cache;
private long expiryInSeconds;
private VogonService service;
public CachedVogonService(VogonService newService,
long newExpiryInSeconds) {
this.expiryInSeconds = newExpiryInSeconds;
this.service = newService;
this.cache = createCache(newService, newExpiryInSeconds);
}
private LoadingCache<String, Vogon> createCache(
VogonService newService,
long expiryInSeconds) {
return CacheBuilder.newBuilder()
.refreshAfterWrite(expiryInSeconds, TimeUnit.SECONDS)
.build(new VogonCacheLoader(
Executors.newCachedThreadPool(), newService));
}
/**
* This is the method I am exposing in JMX
*/
@Override
public void setExpiryInSeconds(long newExpiryInSeconds) {
this.expiryInSeconds = newExpiryInSeconds;
synchronized (this.cache) {
this.cache = createCache(service, expiryInSeconds);
}
}
I'm worried that my locking technique will cause the JVM to keep a reference to the old cache and prevent it being garbage collected.
If my service object loses the reference to the old cache inside the synchronized block, then when execution exits the block, might it then leave the old cache object still marked as locked - making it unavailable for garbage collection?