我试图在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
我是"做"单身人士错了,或者我的代码有错误吗?
答案 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个虚拟机中的不同单例对象。