萨拉万·库玛(Saravan Kumar),
我了解您提出问题的动机。 在开始从事编译器工作之前,我也有一个非常相似的想法,希望了解Java虚拟机的内部。
首先,您的问题给我留下了深刻的印象。 为了解决您的问题,需要有几点区别和理解。 首先:Singleton模式(有时甚至称为反模式)确保JVM(Java虚拟机)只有该类的一个实例。 这意味着我们实质上是在应用程序中引入全局状态。 我知道您了解这一点,但这只是一个澄清点。
现在是内部。
创建类的实例时,我们将创建一个驻留在JVM共享内存中的对象。 现在,这些线程正在独立执行在这些实例上运行的代码。 每个线程都有一个工作内存,在其中保存所有线程之间共享的主内存中的数据。 这是对您创建的Singleton对象的引用所在的位置。 本质上,正在发生的事情是在这些线程的每个线程上执行生成的字节码,该字节码代表您创建的单例对象。
现在,如何发生这种情况的内幕如下:
每个JVM线程都有一个专用JVM堆栈,与该线程同时创建。现在,JVM具有一个在所有JVM线程之间共享的堆。堆是运行时数据区,从中分配所有类实例和数组的内存。堆是在VM启动时创建的。当线程请求单例实例时,它将指向此Singleton的字节码所在的堆中的引用。它将执行适当的代码。在您的情况下,它将对第一个请求执行第一个方法,对第二个请求执行第二个方法。之所以能够这样做,是因为没有锁或限制可以阻止编译器将程序计数器指向分配此实例的堆中的区域。 Singleton类对Java虚拟机的唯一限制是,该类的堆中只能有一个实例。就是这样。除此之外,您可以从方法中引用它100次,编译器将指向相同的字节码并简单地执行它。这就是为什么我们通常希望Singleton类为无状态的原因,因为如果我们有任何线程访问它,由于缺少并发控制,我们不希望内部变量发生突变。
请让我知道,如果你有任何问题!