java - Java中的单例(线程安全) - 一旦没有人使用该对象,如何销毁成员?

标签 java thread-safety singleton

我有一个同步单例类,其中包含一个维护连接的私有(private)成员(ZookeeperClient),需要在该类不再使用时关闭。

我如何设计/使用这个单例,以便当所有线程不再使用它时,正确关闭/销毁这个私有(private)成员?我不确定在这种情况下如何设计 close()@override Finalize() 方法...

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
}

最佳答案

您可以使用简单的引用计数。如果类中有一个内部计数器并在 getInstance() 上递增它。然后您需要一个方法,例如 release(),在其中递减计数器。一旦计数器达到 0,就不再有对您的对象的引用,您可以清理它。

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;
         }
     }
}

但是,正如评论中所建议的,您绝对确定需要这个逻辑吗?也许这里不使用单例会更容易,直接使用 ZooKeeperClient 即可。

关于java - Java中的单例(线程安全) - 一旦没有人使用该对象,如何销毁成员?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31688028/

相关文章:

java - 如何将字节数组转换为 base64 字符串

java - Spring Framework HttpComponentsClientHttpRequestFactory 线程安全吗?

ios - 单例 SharedInstance 函数被调用两次

c++ - 函数返回引用,失败时返回什么?

java - Spring 3.0 Java REST返回PDF文档

java - 使用方法注释值来定位切入点

java - 为什么在守护线程上调用 Join 不好

angular - 服务在 APP_INITIALIZER 之后实例化了两次

java - 如何在pom.xml中设置Jmeter home?

f# - 什么是由 Observable.merge<'T> 不是线程安全引起的意外后果的例子?