单例变量不会跨系统持久化

时间:2014-05-19 04:46:54

标签: java singleton persistence

我试图在Java中使用单例模式,但遇到了一个问题。我有一个单身ClientCounter,我想跟踪另一个班级Client的实例。

ClientCounter只需在count调用其Client方法时递增addClient()即可:

public class ClientCounter {

    private int count = 0;

    private static final ClientCounter counter = new ClientCounter();

    public static ClientCounter getInstance() {
        return counter;
    }

    public void addClient() {
        count++;
    }

    public int getCount() {
        return count;
    }

}

我的Client代码:

public class Client {

    public static void main(String[] args) {

        ClientCounter myCC = ClientCounter.getInstance();
        myCC.addClient();

        System.out.println("CC Count is " + myCC.getCount());

    }

}

然而,我的count似乎并没有持续存在,就像我尝试在一个接一个地运行两个Client(在不同的终端中)一样,两者的输出是:

CC Count is 1

我是"做"单身人士错了,或者我的代码有错误吗?

4 个答案:

答案 0 :(得分:1)

  

然而,我的计数似乎并没有持续存在,就像我尝试运行两个客户端(在不同的终端中)

根据定义,Singleton pattern将在系统中维护对象的单个实例。在这种情况下,系统是您当前的应用程序,因此如果您多次执行它,则会有多个应用程序实例,并且每个单例对象都绑定到每个应用程序。对于Java应用程序,每个Java应用程序都绑定到JVM;这不适用于Web应用程序,其中Java应用程序是应用程序服务器,应用程序服务器与JVM绑定(在Web应用程序中,单例的行为比这更复杂,但它超出了这个问题的范围/回答)。

如果要在应用程序的多次执行中保留该值,则应将数据存储在应用程序/终端通用的数据源中,可能存储在共享文件或数据库中,并从那里检索多个数据倍。但请注意,不是单身人士的工作,你可能会使用这种方法使事情复杂化。

答案 1 :(得分:0)

您的Singleton实现缺少私有构造函数,因此编写时,其他代码可以创建它的任意实例。您可以通过添加私有构造函数来修复它,以防止其他类构造它。

public class ClientCounter {
     private ClientCounter() {}
}

但是,即使它是正确的,如果它们之间没有明确的通信,您也不能指望任何州持续跨进程

如果您在两个独立的终端中运行两个应用程序,它们具有完全独立的内存虚拟地址空间,并且用于彼此隔离的所有意图和目的。

如果要在应用程序的多个实例之间保留数据,则需要设置服务器进程以保持此状态,并让每个客户端在启动时与服务器进程通信。或者,他们都可以访问共享数据存储(例如数据库)进行同步。

答案 2 :(得分:0)

“当我尝试运行两个客户端(在单独的终端中)时”我假设您的意思是您正在运行您的Java应用程序两次?如果是这样,单例应用于单个JVM(即执行java程序,只是为了简短)。

答案 3 :(得分:0)

单身人士通常仅与ClassLoader相关联。在您的情况下,因为您运行的是2个单独的Java VM,因此它们必然是这2个虚拟机中的不同单例对象。