Singleton (Threadsafe) in Java - how to destroy members once no one is using the object?

时间:2015-07-28 22:12:44

标签: java thread-safety singleton

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
}

1 个答案:

答案 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.