I have a synchronized singleton class that contains a private member (ZookeeperClient) which maintains a connection, requires to be closed when the class is no longer in use.
How do I go about designing/using this singleton such that this private member is properly closed/destroyed when all threads are no longer using it? I'm not sure how to design my close()
or @override finalize()
method in this case...
public class SynchroSingletonClass {
private static SynchroSingletonClass instance;
private ZooKeeperClient mZookeeperClient; // needs to be closed properly via .close()
private SynchroSingletonClass() {
mZookeeperClient = new ZooKeeperClient(Amount.of(1, Time.DAYS), getZookeeperAddresses());
}
public static synchronized SynchroSingletonClass getInstance(){
if (instance == null){
instance = new SynchroSingletonClass();
}
return instance;
}
...some more methods for the class
}
答案 0 :(得分:0)
You can go with simple reference counting. If you have an internal counter in the class and increment it on getInstance()
. Then you need a method, for example release()
, in which you decrement the counter. Once the counter reaches 0, there are no more references to your object and you can clean it.
public class ReferenceCountedClass {
private static ReferenceCountedClass instance;
private static int references;
private ReferenceCountedClass() {
}
public static synchronized ReferenceCountedClass getInstance() {
if (instance == null) {
instance = new ReferenceCountedClass();
}
references++;
return instance;
}
public synchronized void release() {
if (0 == references) {
return;
}
references--;
if (0 == references) {
// please cleanup logic here
instance = null;
}
}
}
But, as suggested in the comments, are you absolutely sure you need this logic? Maybe it would be easier to not go with a singleton here, and just use ZooKeeperClient directly.